- Room是一个对象关系映射模型(ORM)用来操作Android自带的SQLite数据库的一个库,主要是为了简化访问Android本地数据库。
- 框架由三个部分组成:Database、Entity、Dao
Database
Database就是代表着数据库,内部有一张张的表。
定一个数据库
@Database(entities = [User.class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
- 定义一个抽象类,必须继承自RoomDatabase
- 抽象类使用
@DataBase
注解标记 -
@DataBase
注解中entities属性定义了该数据库拥有的表有哪些,version定义了数据库的版本 - 抽象类中定义了无参的抽象方法,返回一个Dao对象(用于操作数据库中表)
Database在定义的时候上面还可以用@TypeConverters注解,用于将某个类型转换成数据库能够存储的类型,例如将某个实体类序列化转成String类型存到数据库,取的时候再反序列化
创建数据库
mAppDatabase = Room.databaseBuilder(getApplicationContext(), AppDatabase::class.java, "app.db")
.build();
创建数据库的时候采用Room提供的Builder方法进行创建,就可以拿到数据库的引用。创建数据库最好设计成单例,全局只初始化一次。
数据库升级
mAppDatabase = Room.databaseBuilder(getApplicationContext(), AppDatabase::class.java, "app.db")
.addMigrations(MIGRATION_1_2)
.build();
/**
* 数据库版本 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")
}
}
迭代的过程中升级Android本地数据库正确的做法是,在上面的@DataBase
注解中升级version属性的版本号,同时在创建DB的实例的时候调用addMigrations
api提供Migration实例进行数据迁移。
Entity
每个Entity类代表了数据库中的一张表,Entity的每个字段对应的是数据库中的一列
@Entity(tableName = "user_info")
data class User {
@PrimaryKey
var id = 0
var firstName: String? = null
var lastName: String? = null
}
- 类用
@Entity
注解标记,tableName定义对应的表的表名 -
@PrimaryKey
标识字段对应的列作为主键
Dao
dao层定义这操作数据库中表的CRUD的操作,注解标识的方法Room会自动生成该方法的一个实现进行数据库表的操作。
@Insert
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(user: User)
onConflict属性有5个枚举的取值
- OnConflictStrategy.REPLACE:冲突时取代旧数据同时继续事务
- OnConflictStrategy.ROLLBACK:冲突时是回滚事务
- OnConflictStrategy.ABORT:冲突时终止事务
- OnConflictStrategy.FAIL:冲突时事务失败
- OnConflictStrategy.IGNORE:冲突时忽略冲突
@Update
@Update(onConflict = OnConflictStrategy.REPLACE)
suspend fun updateUsers(vararg users: User)
Room会根据传进来的User的主键定义的值去匹配数据库表中的数据去更新对应的数据。
@Delete
@Delete(onConflict = OnConflictStrategy.REPLACE)
suspend fun deleteUsers(vararg users: User)
同样Room会根据传进来的User的主键定义的值去匹配数据库表中的数据去删除对应的数据。
@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>
同时也可以将数据返回成LiveData提供上层进行监听。
@Query("SELECT * FROM user_info")
suspend fun queryAll(): LiveData<List<User>>
网友评论