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替代