欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于room的那些事

程序员文章站 2022-05-06 18:20:09
...

Room是一个数据持久化库,它是 Architecture Component的一部分。封装了sqlite。它让SQLiteDatabase的使用变得简单,大大减少了重复的代码,并且把SQL查询的检查放在了编译时。
先介绍下基本的使用吧

1. 添加依赖

dependencies{
 //roomData
    implementation "androidx.room:room-runtime:$rootProject.roomVersion"
    kapt "androidx.room:room-compiler:$rootProject.roomVersion"
    }

2.建表

我们需要为我们建造的实体数据加入@Entity注解
这里建造一个BlackInfo表,
用@Entity注解这个类并用tableName属性设置表的名称。
使用 @PrimaryKey 注解把一个成员设置为主键,这里我们的主键是BlackInfo的index,需要自增的话使用autoGenerate = true,默认为false
使用@ColumnInfo(name = “column_name”) 注解设置成员对应的列名。如果你觉得成员变量名就本身就可以作为列名,也可以不设置。
使用 @Ignore注解告诉Room哪个用,哪个不用。默认全部加入到表中字段

@Entity(tableName = "BlackInfo")
data class BlackInfo(
        @ColumnInfo(name = "indexs")
        @PrimaryKey(autoGenerate = true)
        var index: Int = 0,

        @ColumnInfo(name = "guid")
        var guid: String? = null,

        @ColumnInfo(name = "class")
        var className: String? = null,

        @ColumnInfo(name = "address")
        var address: String? = null,

        @ColumnInfo(name = "name")
        var name: String? = null,

        @ColumnInfo(name = "flag")
        var flag: Int = 0,

        @ColumnInfo(name = "isUpdate")
        var isUpdate: Int = 0,

        @ColumnInfo(name = "dateTime")
        var dateTime: Long = 0
)

3.操作数据表,建造DAO

我们想要操作我们的数据表就需要创建一个DAO ----- 一个实体表,我们都需要建造一个对应的DAO来进行数据操作
创建一个接口使用@Dao注解
@Query 使用自定义的sql 查询数据,我们也可以用来进行其他操作,比如如果想要不根据主键删除某条数据,我们也可以使用Query注解来操作,比如我想根据guid(非主键)来删除。可以这么写 @Query(“delete from BlackInfowhere guid =(:guid)”)
@Insert 插入数据 onConflict = OnConflictStrategy.REPLACE指定主键冲突时候的解决方式。直接替换。
@Update 更新数据
@Delete 删除数据

@Dao
interface BlackInfoDao {
 /**
     * 插入一项 黑名单
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertBlackInfo(blackInfo: BlackInfo)
/**
     * 查找所有黑名单数据
     */
    @Query("select * from blackInfo")
    fun queryAllBlackInfo(): List<BlackInfo>
    
    @Query("select * from blackInfo where name = :name")
    fun queryBlackInfoByName(name: String): List<BlackInfo>
}

4.建造数据库

新建一个类,继承RoomDatabase,我们需要它来获取我们的DAO
注解@Database(entities = [BlackInfo::class],version = 1, exportSchema = false)

@Database(entities = [BlackInfo::class], version = Configure.dataBaseVersion, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {

   //abstract fun getBlackInfoDao(): BlackInfoDao
    }

创建Database 我这样fallbackToDestructiveMigration()创建,每次数据库升级的时候,不会保留原有的用户数据 ,如果你想要保留原有的数据 就需要使用Migration

//不保留数据
val appDatase = Room.databaseBuilder(context, AppDatabase::class.java, "dbName") .fallbackToDestructiveMigration().build()

//保留原有数据
val appDatase = Room.databaseBuilder(context, AppDatabase::class.java, "dbName")  .addMigrations(MIGRATION_1_2).build()
 private val MIGRATION_1_2 = object : Migration(1, 2) {
        override fun migrate(database: SupportSQLiteDatabase) {
            // Since we didn't alter the table, there's nothing else to do here.
		/如果我们修改了表的属性(增加字段,删除字段。修改字段属性等)
		//我们就需要在这里进行数据迁移 
		//1.建造临时表  2.迁移原表到临时表  3.删除原表 4.重命名临时表
        	 database.execSQL("alter table BlackInfoadd iconUrl TEXT ")
        }
    }


在迁移表数据的时候,建造临时表字段属性需要与建造的实体BlackInfo字段属性一一对应。如果报错Migration didn't properly handle 一般字段属性不一致导致,检查下每个字段名称和属性,能否为空,字段类型等。room 里面字段类型sql语句,String都可以使用Text替代