jetpack系列-Room的使用和升级

528 阅读2分钟

创建

添加Entity

@Entity(tableName = "table_user")
data class UserEntity(
    @PrimaryKey(autoGenerate = true)
    val id: Long? = null,
    @ColumnInfo(name = "user_name", defaultValue = "new_user")
    var userName: String? = null,

    val password: String? = null,

    val age: Int? = null
) {
    override fun toString(): String {
        return "$id,$userName,$password,$age"
    }
}
  • @Entity为实体类标示
  • tableName为自定义表名,不填默认使用类名作为表名
  • @PrimaryKey主键标示,autoGenerate 主键自增
  • @ColumnInfo 设置字段的信息

添加Dao

@Dao
interface UserDao {
    @Insert
    suspend fun insert(userEntity: UserEntity)

    @Update
    suspend fun update(userEntity: UserEntity)

    @Delete
    suspend fun delete(userEntity: UserEntity)

    @Query("select * from table_user")
    suspend fun queryAll(): List<UserEntity>?

    @Query("select * from table_user where id=:id")
    suspend fun queryById(id: Long): UserEntity?

    @Query("delete from table_user")
    suspend fun deleteAll()
}
  • @Dao为数据库操作类标示
  • @Insert,@Update,@Delete,@Query为数据库操作类型,@Query可自定义查询语句

由于数据库操作属于耗时操作,这里使用suspend标示,后面使用协程进行处理。 编译后会生成这个接口类的实现UserDao_Impl 里面有具体的实现

数据库的初始化

创建AppDatabase继承RoomDatabase

@Database(entities = [UserEntity::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null

        //App.instance自定义继承Application的类
        fun getInstance(): AppDatabase =
            INSTANCE ?: synchronized(this) {
                INSTANCE
                    ?: buildDatabase(App.instance()).also { INSTANCE = it }
            }

        private fun buildDatabase(context: Context): AppDatabase {
            return Room.databaseBuilder(
                context.applicationContext,
                AppDatabase::class.java, "hsw_db" //自定义数据库的名称
            ).build()
        }
    }

    abstract fun userDao(): UserDao
}
  • 创建抽象类AppDatabase的单例,构造database,主要传入Context和数据库名称
  • 创建抽象方法获取Dao对象

更新

基础数据类型

我们常用的sqlite基本数据类型主要是

  • INTEGER(整型包含Long)
  • TEXT (字符串文本)
  • REAL(浮点型)

忽略大小写

有时候会遇到字符串查询一直查不到,根据实际情况忽略大小写能解决这个问题

在查询语句后面加上COLLATE NOCASE

更新字段

  • 修改AppDatabase 中的version,一般+1
  • 增加MIGRATION_old_new定义修改或者增加的内容
private val MIGRATION_1_2 = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL(
                    "create table `table_product` (`id` INTEGER, `product_name` TEXT, `price` REAL, PRIMARY KEY (`id`))"
                )
            }
        }

在build中添加修改内容即可

private fun buildDatabase(context: Context): AppDatabase {
            return Room.databaseBuilder(
                context.applicationContext,
                AppDatabase::class.java, "hsw_db"
            ).addMigrations(MIGRATION_1_2)
                .build()
        }

这个是增加表的操作,修改字段等操作可以修改sql语句即可,如果失败请先确认sql语句是否正确(是否少了括号等)

操作数据库

private val userDao by lazy {
        AppDatabase.getInstance().userDao()
    }
userDao.update(userEntity)
userDao.delete(userEntity)
userDao.queryAll()

示例DEMO