JetPack之Room數(shù)據(jù)庫框架學(xué)習(xí)

  • Room是一個(gè)對(duì)象關(guān)系映射模型(ORM)用來操作Android自帶的SQLite數(shù)據(jù)庫的一個(gè)庫,主要是為了簡化訪問Android本地?cái)?shù)據(jù)庫。
  • 框架由三個(gè)部分組成:Database、Entity、Dao

Database

Database就是代表著數(shù)據(jù)庫,內(nèi)部有一張張的表。

定一個(gè)數(shù)據(jù)庫

@Database(entities = [User.class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}
  • 定義一個(gè)抽象類,必須繼承自RoomDatabase
  • 抽象類使用@DataBase注解標(biāo)記
  • @DataBase注解中entities屬性定義了該數(shù)據(jù)庫擁有的表有哪些,version定義了數(shù)據(jù)庫的版本
  • 抽象類中定義了無參的抽象方法,返回一個(gè)Dao對(duì)象(用于操作數(shù)據(jù)庫中表)

Database在定義的時(shí)候上面還可以用@TypeConverters注解,用于將某個(gè)類型轉(zhuǎn)換成數(shù)據(jù)庫能夠存儲(chǔ)的類型,例如將某個(gè)實(shí)體類序列化轉(zhuǎn)成String類型存到數(shù)據(jù)庫,取的時(shí)候再反序列化

創(chuàng)建數(shù)據(jù)庫

 mAppDatabase = Room.databaseBuilder(getApplicationContext(), AppDatabase::class.java, "app.db")
                           .build();

創(chuàng)建數(shù)據(jù)庫的時(shí)候采用Room提供的Builder方法進(jìn)行創(chuàng)建,就可以拿到數(shù)據(jù)庫的引用。創(chuàng)建數(shù)據(jù)庫最好設(shè)計(jì)成單例,全局只初始化一次。

數(shù)據(jù)庫升級(jí)

  mAppDatabase = Room.databaseBuilder(getApplicationContext(), AppDatabase::class.java, "app.db")
                           .addMigrations(MIGRATION_1_2)
                           .build();
                           
   /**
     * 數(shù)據(jù)庫版本 1->2 user表格新增了age列
     */
   private val MIGRATION_1_2: Migration = object : Migration(1, 2) {
      override fun migrate(database: SupportSQLiteDatabase) {
          atabase.execSQL("ALTER TABLE User ADD COLUMN age integer")
      }
   }

迭代的過程中升級(jí)Android本地?cái)?shù)據(jù)庫正確的做法是,在上面的@DataBase注解中升級(jí)version屬性的版本號(hào),同時(shí)在創(chuàng)建DB的實(shí)例的時(shí)候調(diào)用addMigrationsapi提供Migration實(shí)例進(jìn)行數(shù)據(jù)遷移。

Entity

每個(gè)Entity類代表了數(shù)據(jù)庫中的一張表,Entity的每個(gè)字段對(duì)應(yīng)的是數(shù)據(jù)庫中的一列

@Entity(tableName = "user_info")
data class User {
    @PrimaryKey
    var id = 0
    var firstName: String? = null
    var lastName: String? = null
}
  • 類用@Entity注解標(biāo)記,tableName定義對(duì)應(yīng)的表的表名
  • @PrimaryKey標(biāo)識(shí)字段對(duì)應(yīng)的列作為主鍵

Dao

dao層定義這操作數(shù)據(jù)庫中表的CRUD的操作,注解標(biāo)識(shí)的方法Room會(huì)自動(dòng)生成該方法的一個(gè)實(shí)現(xiàn)進(jìn)行數(shù)據(jù)庫表的操作。

@Insert

 @Insert(onConflict = OnConflictStrategy.REPLACE)
 suspend fun insert(user: User)

onConflict屬性有5個(gè)枚舉的取值

  • OnConflictStrategy.REPLACE:沖突時(shí)取代舊數(shù)據(jù)同時(shí)繼續(xù)事務(wù)
  • OnConflictStrategy.ROLLBACK:沖突時(shí)是回滾事務(wù)
  • OnConflictStrategy.ABORT:沖突時(shí)終止事務(wù)
  • OnConflictStrategy.FAIL:沖突時(shí)事務(wù)失敗
  • OnConflictStrategy.IGNORE:沖突時(shí)忽略沖突

@Update

@Update(onConflict = OnConflictStrategy.REPLACE)
suspend fun updateUsers(vararg users: User)

Room會(huì)根據(jù)傳進(jìn)來的User的主鍵定義的值去匹配數(shù)據(jù)庫表中的數(shù)據(jù)去更新對(duì)應(yīng)的數(shù)據(jù)。

@Delete

@Delete(onConflict = OnConflictStrategy.REPLACE)
suspend fun deleteUsers(vararg users: User)

同樣Room會(huì)根據(jù)傳進(jìn)來的User的主鍵定義的值去匹配數(shù)據(jù)庫表中的數(shù)據(jù)去刪除對(duì)應(yīng)的數(shù)據(jù)。

@Query

@Query("SELECT * FROM user_info")
suspend fun queryAll(): List<User>

@Query("SELECT * FROM user_info WHERE firstName == :name")
suspend fun queryUsersByFirstName(name: String): List<User>

同時(shí)也可以將數(shù)據(jù)返回成LiveData提供上層進(jìn)行監(jiān)聽。

@Query("SELECT * FROM user_info")
suspend fun queryAll(): LiveData<List<User>>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容