Room的踩坑记录

一、建立实体类踩坑记录

1、实体类字段问题

由于我用的是kotlin建立的实体类,kotlin对于空指针的检查很严格,所以,对于一些可以为空的数据表字段需要在实体类属性后面加上 ? 表示可以为空,不能为空的字段就不加?,当然使用Java的时候,就没有这些问题了。

@Entity(tableName = "Test", indices = [Index( "TEST_ID", unique = true)])
data class Test(
    @ColumnInfo(name = "TEST_ID") var testId: String?, //表示可以为空
) {
     
    @PrimaryKey(autoGenerate = true)
    var _id: Long = 0
}

2、索引问题

说说索引问题,之前用的是greenDao来处理数据库的,greenDao的处理索引的方式和Room不一样,greenDao的索引是IDX开头的,而Room的处理的索引是index开头的,直接迁移的时候(db文件),就会导致报错,就需要特殊处理一下。我之前用的是,在Room的升级方法中删除原来的索引再建立新的索引,这种方式也会报错,会报没有发现这个索引的错误。

         //数据库升级,从22->23
        private val MIGRATION_22_23 = object : Migration(22, 23) {
     
            override fun migrate(database: SupportSQLiteDatabase) {
     
                database.execSQL("DROP INDEX TOPIC_COLLECTION.IDX_TOPIC_COLLECTION_QUESTION_ID")
                database.execSQL("CREATE UNIQUE INDEX index__TOPIC_COLLECTION_QUESTION_ID ON TOPIC_COLLECTION(QUESTION_ID)")
            }
        }

​ 最后删除表,再重新建立表,就不会出问题。但是这样的话,对于字段多的表就很不友好,最后是直接改的数据库里面的表,这样的话,还需要考虑数据迁移的问题,得保存用户之前的数据,暂时还没有想到好的解决办法。由于公司这个是一个新项目,所以就没有考虑数据迁移的问题。如果有好的方法欢迎留言交流。

3、直接导入现有的db文件

我用的方法是在建立数据库时,使用createFromAsset()这个方法。

Room.databaseBuilder(
    context.applicationContext,
    AppDatabase::class.java,
    databaseName)
    .createFromAsset("Test.db")
    .addMigrations(MIGRATION_22_23)
    .build()
    .apply {
     
        instance = this
    }

二、Dao层使用踩坑记录

1、关于方法返回值问题

众所周知,使用@Insert注解会有返回值,这个返回值是返回表的id,一般用Long类型来接,我用Int类型来接就报错了,但是还需要在@Insert中添加当前是哪个表需要插入,需要添加entity参数,这样就可以愉快接收返回值了,其他的注解也是类似,@Query除外。

@Insert(onConflict = OnConflictStrategy.REPLACE, entity = QuestionBankCollect::class)

2、关于sql 中like关键字使用方法

like '%'||:carType||'%'

3、@Insert和@Update的问题

  • 使用@insert注解时,不能用自增的id当做主键,每次插入时,表中永远只有一条数据,建议使用其他值不一样的当做主键,看各自的业务场景使用
  • 使用@update注解时,不会往表里插入新增的数据

最后再提一句,一定要放在子线程或者协程中调用数据库方法。

你可能感兴趣的:(踩坑记录,数据库,android)