在 Android 項(xiàng)目中使用 Room 可以通過(guò)以下步驟實(shí)現(xiàn):
1帆喇、添加 Room 的依賴(lài)
在項(xiàng)目的 build.gradle 文件中添加以下依賴(lài):
dependencies {
...
implementation "androidx.room:room-runtime:<version>"
kapt "androidx.room:room-compiler:<version>"
}
2、創(chuàng)建 Entity
使用 @Entity 注解創(chuàng)建一個(gè)數(shù)據(jù)表實(shí)體類(lèi)亿胸,其中可以使用 @PrimaryKey 注解設(shè)置主鍵坯钦,@ColumnInfo 注解設(shè)置列名等。
例如:
@Entity(tableName = "users")
data class User(
@PrimaryKey val id: Int,
@ColumnInfo(name = "name") val name: String,
@ColumnInfo(name = "email") val email: String
)
3损敷、創(chuàng)建 DAO
使用 @Dao 注解創(chuàng)建數(shù)據(jù)訪問(wèn)對(duì)象葫笼,定義訪問(wèn)數(shù)據(jù)庫(kù)的方法∞致可以使用 @Query 注解執(zhí)行 SQL 查詢(xún)路星,也可以使用其他注解進(jìn)行數(shù)據(jù)操作。
例如:
@Dao
interface UserDao {
@Query("SELECT * FROM users")
fun getAll(): List<User>
@Insert
fun insertAll(vararg users: User)
}
4诱桂、創(chuàng)建 Room 數(shù)據(jù)庫(kù)
使用 @Database 注解創(chuàng)建 Room 數(shù)據(jù)庫(kù)洋丐,并指定包含 Entity 的數(shù)組和版本號(hào)。
例如:
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
5挥等、初始化 Room 數(shù)據(jù)庫(kù)
在 Application 類(lèi)中創(chuàng)建 Room 數(shù)據(jù)庫(kù)的實(shí)例友绝。
例如:
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
@HiltAndroidApp
class MyApplication : Application() {
val db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java, "my-database"
).build()
}
6、使用 Room 數(shù)據(jù)庫(kù)
通過(guò) Room 數(shù)據(jù)庫(kù)的實(shí)例訪問(wèn) DAO肝劲,執(zhí)行數(shù)據(jù)操作迁客。
例如:
val userDao = (application as MyApplication).db.userDao()
val users = userDao.getAll()
userDao.insertAll(User(1, "Alice", "alice@example.com"))
以上是在 Android 項(xiàng)目中使用 Room 的基本步驟,可以根據(jù)實(shí)際需求進(jìn)行調(diào)整辞槐。
除了基本的使用方法之外掷漱,Room 還提供了以下功能:
(1)、使用 LiveData 自動(dòng)更新 UI
可以在 DAO 的查詢(xún)方法上使用 LiveData 返回?cái)?shù)據(jù)榄檬,從而在數(shù)據(jù)變化時(shí)自動(dòng)更新 UI卜范。
例如:
@Dao
interface UserDao {
@Query("SELECT * FROM users")
fun getAll(): LiveData<List<User>>
}
在 UI 組件中觀察 LiveData,當(dāng)數(shù)據(jù)變化時(shí)會(huì)自動(dòng)更新 UI鹿榜。
userViewModel.allUsers.observe(this, Observer { users ->
// Update UI
})
(2)海雪、使用關(guān)系映射
可以在 Entity 類(lèi)中使用 @Relation 注解定義與其他表的關(guān)系,從而方便地訪問(wèn)關(guān)聯(lián)數(shù)據(jù)舱殿。
例如:
data class UserWithPets(
@Embedded val user: User,
@Relation(
parentColumn = "id",
entityColumn = "user_id"
)
val pets: List<Pet>
)
在 DAO 中查詢(xún)數(shù)據(jù)時(shí)奥裸,使用 @Transaction 注解可以在單個(gè)事務(wù)中執(zhí)行多個(gè)操作。
例如:
@Transaction
@Query("SELECT * FROM users WHERE id = :userId")
fun getUserWithPets(userId: Int): LiveData<UserWithPets>
(3)怀薛、數(shù)據(jù)庫(kù)遷移
當(dāng)需要更改數(shù)據(jù)庫(kù)結(jié)構(gòu)時(shí)刺彩,可以使用 Room 提供的數(shù)據(jù)庫(kù)遷移機(jī)制。在 AppDatabase 中使用 @Database 注解時(shí)指定 migration 數(shù)組枝恋,即可在升級(jí)版本時(shí)執(zhí)行相應(yīng)的遷移操作创倔。
例如:
@Database(entities = [User::class], version = 2, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
...
companion object {
val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE users ADD COLUMN age INTEGER NOT NULL DEFAULT 0")
}
}
}
...
}
在創(chuàng)建數(shù)據(jù)庫(kù)實(shí)例時(shí)指定 migration 數(shù)組即可進(jìn)行數(shù)據(jù)遷移。
例如:
val db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java,
"my-database"
)
.addMigrations(AppDatabase.MIGRATION_1_2)
.build()
(4)焚碌、使用 TypeConverters 進(jìn)行數(shù)據(jù)類(lèi)型轉(zhuǎn)換
在 Entity 類(lèi)中可以使用 @TypeConverters 注解指定一個(gè)或多個(gè)類(lèi)型轉(zhuǎn)換器畦攘,將不支持的數(shù)據(jù)類(lèi)型轉(zhuǎn)換為 Room 支持的數(shù)據(jù)類(lèi)型,或?qū)?Room 支持的數(shù)據(jù)類(lèi)型轉(zhuǎn)換為應(yīng)用程序中的自定義類(lèi)型十电。
例如:
@Entity
data class User(
@PrimaryKey val id: Int,
@ColumnInfo(name = "name") val name: String,
@ColumnInfo(name = "birthdate") val birthdate: Date
)
class Converters {
@TypeConverter
fun fromTimestamp(value: Long?): Date? {
return value?.let { Date(it) }
}
@TypeConverter
fun dateToTimestamp(date: Date?): Long? {
return date?.time
}
}
@Database(entities = [User::class], version = 1)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
...
}
(5)知押、使用 RxJava 進(jìn)行異步操作
在 DAO 中使用 RxJava 的 Observable 或 Single 對(duì)象,可以進(jìn)行異步數(shù)據(jù)操作鹃骂,并使用 RxJava 提供的操作符進(jìn)行數(shù)據(jù)轉(zhuǎn)換台盯、篩選、組合等操作畏线。
例如:
@Dao
interface UserDao {
@Query("SELECT * FROM users")
fun getAll(): Observable<List<User>>
@Insert
fun insert(user: User): Single<Long>
}
userDao.getAll()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { users ->
// Update UI
}
userDao.insert(User(1, "Alice", Date()))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { id ->
// Show success message
}
(6)静盅、使用協(xié)程進(jìn)行異步操作
在 DAO 中使用協(xié)程的 suspend 函數(shù),可以進(jìn)行異步數(shù)據(jù)操作寝殴,并使用協(xié)程提供的操作符進(jìn)行數(shù)據(jù)轉(zhuǎn)換蒿叠、篩選、組合等操作蚣常。
例如:
@Dao
interface UserDao {
@Query("SELECT * FROM users")
suspend fun getAll(): List<User>
@Insert
suspend fun insert(user: User): Long
}
GlobalScope.launch(Dispatchers.IO) {
val users = userDao.getAll()
withContext(Dispatchers.Main) {
// Update UI
}
}
GlobalScope.launch(Dispatchers.IO) {
val id = userDao.insert(User(1, "Alice", Date()))
withContext(Dispatchers.Main) {
// Show success message
}
}