Room 数据库介绍和使用
1. 介绍
Room 是 Android 提供的一个持久化库,作为 SQLite 的抽象层,它简化了数据库访问,同时保证了在编译时对 SQLite 查询的验证。Room 提供了以下主要组件:
- Entity:表示数据库中的表。
- DAO (Data Access Object):定义用于访问数据库的方法。
- Database:提供数据库连接并管理实体和 DAO。
Room 的主要优点包括减少样板代码、编译时检查 SQL 查询以及与 Kotlin 协程和 LiveData 的无缝集成。
2. 基本使用
添加依赖
首先,在你的 build.gradle 文件中添加 Room 的依赖:
dependencies {
implementation "androidx.room:room-runtime:2.5.0"
kapt "androidx.room:room-compiler:2.5.0"
implementation "androidx.room:room-ktx:2.5.0"
}
创建 Entity
一个 Entity 表示数据库中的一张表。使用 @Entity 注解来定义一个实体类。例如,创建一个用户表:
@Entity(tableName = "users")
data class User(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
val name: String,
val age: Int
)
定义 DAO
DAO 是用于访问数据库的方法集合。使用 @Dao 注解来定义一个 DAO 接口。例如:
@Dao
interface UserDao {
@Insert
suspend fun insertUser(user: User)
@Query("SELECT * FROM users WHERE id = :userId")
suspend fun getUserById(userId: Int): User?
@Query("SELECT * FROM users")
suspend fun getAllUsers(): List<User>
@Delete
suspend fun deleteUser(user: User)
}
创建 Database
Database 类作为数据库的主要访问点,并持有数据库的连接。使用 @Database 注解来定义一个数据库类:
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
使用 Room 数据库
在应用程序中使用 Room 数据库:
val db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java, "database-name"
).build()
val userDao = db.userDao()
// 插入用户
val user = User(name = "John", age = 25)
userDao.insertUser(user)
// 查询所有用户
val users = userDao.getAllUsers()
// 根据 ID 查询用户
val retrievedUser = userDao.getUserById(userId = 1)
// 删除用户
userDao.deleteUser(user)
3. 使用协程和 LiveData
Room 与 Kotlin 协程和 LiveData 无缝集成,提供了更好的异步处理和响应式编程支持。
使用协程
协程可以简化异步操作,在 Room 中,所有数据库操作都应该在非主线程中执行。例如:
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
CoroutineScope(Dispatchers.IO).launch {
val user = User(name = "John", age = 25)
userDao.insertUser(user)
}
使用 LiveData
LiveData 是一种可观察的数据持有者类,用于将数据库数据的变化通知到 UI 层。例如:
@Dao
interface UserDao {
@Query("SELECT * FROM users")
fun getAllUsers(): LiveData<List<User>>
}
在 ViewModel 中使用:
class UserViewModel(application: Application) : AndroidViewModel(application) {
private val userDao: UserDao = AppDatabase.getDatabase(application).userDao()
val allUsers: LiveData<List<User>> = userDao.getAllUsers()
}
在 Activity 或 Fragment 中观察数据变化:
userViewModel.allUsers.observe(this, Observer { users ->
// 更新 UI
})
4. 数据库迁移
当需要更改数据库结构时,必须处理数据库迁移。Room 提供了灵活的迁移策略。
例如,添加一个新列:
@Database(entities = [User::class], version = 2)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
companion object {
private var INSTANCE: AppDatabase? = null
fun getDatabase(context: Context): AppDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"database-name"
)
.addMigrations(MIGRATION_1_2)
.build()
INSTANCE = instance
instance
}
}
private val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE users ADD COLUMN lastName TEXT")
}
}
}
}
结论
Room 提供了一种简洁、易于使用的方式来处理 Android 应用中的数据库操作。通过使用 Room,可以显著减少处理 SQLite 数据库的样板代码,并受益于编译时检查和强类型保证。结合协程和 LiveData,Room 进一步提升了应用的响应速度和用户体验。
更多room相关内容可以查看官方文档: 使用room将数据保存到本地数据库