Room是Google推出的Android架构组件库中的数据持久化组件库, 也可以说是在SQLite上实现的一套ORM解决方案。
一、简介 Room是Google提供的一个ORM库。Room提供了三个主要的组件:
Entity:实体类,对应的是数据库的一张表结构。需要使用注解 @Entity 标记。
Dao:包含访问一系列访问数据库的方法。需要使用注解 @Dao 标记。
Database:数据库持有者,作为与应用持久化相关数据的底层连接的主要接入点。需要使用注解 @Database 标记。 使用@Database注解需满足以下条件: 定义的类必须是一个继承于RoomDatabase的抽象类。 在注解中需要定义与数据库相关联的实体类列表。 包含一个没有参数的抽象方法并且返回一个带有注解的 @Dao。
二、基本使用 1、添加依赖 def room_version = "2.2.5" implementation "androidx.room:room-runtime:$room_version" //kotlin下使用 kapt "androidx.room:room-compiler:$room_version" //java下使用 annotationProcessor "androidx.room:room-compiler:$room_version"
在kotlin中使用需要添加kapt插件,在app的build.gradle文件的最上方添加如下代码:
apply plugin: 'kotlin-kapt'
2、Entity 实体类配置 使用@Entity注解实体类
@Entity data class User( @PrimaryKey(autoGenerate = true) var id: Long, var name: String, var age: Int, var onLine: Boolean, @Ignore var remark: String, var mobile:String ){ constructor() : this(0,"",0,false,"","") }
注解说明:
@Entity:定义表名、复合主键、索引等
tableName:设置表名字。默认是类的名字。
indices:设置索引。
inheritSuperIndices:父类的索引是否会自动被当前类继承。
primaryKeys:设置联合主键。
foreignKeys:设置外键。
ignoredColumns : 被忽略的字段。
@PrimaryKey:定义主键,autoGenerate设置是否自增
@ColumnInfo:定义字段名,name设置表中字段名,不设置默认为属性名
@Ignore:定义属性不被创建在表中
3、创建 Dao 数据访问类 Dao类是一个 interface,其中定义了一系列的操作数据库的方法。通常我们操作数据库无非就是增删改查。Room也为我们的提供了相关的注解,有@Insert、@Delete、@Update 和 @Query。
@Dao interface UserDao { //查询所有用户 @Query("select * from user") fun getUsers(): List<User> //根据ID查询用户 @Query("select * from user where id = :id") fun getUserById(id: Long): User //根据用户名模糊查询用户 @Query("select * from user where name Like '%' || :name ||'%'") fun getUsersByName(name: String): List<User> //根据用户名和年龄查询用户 @Query("select * from user where name =:name and age >:age") fun getUsersByNameAndAge(name: String, age: Int): List<User> //插入用户 /* onConflict:默认值是OnConflictStrategy.ABORT,表示当插入有冲突的时候的处理策略。 OnConflictStrategy封装了Room解决冲突的相关策略: 1. OnConflictStrategy.REPLACE:冲突策略是取代旧数据同时继续事务。 2. OnConflictStrategy.ROLLBACK:冲突策略是回滚事务。 3. OnConflictStrategy.ABORT:冲突策略是终止事务。 4. OnConflictStrategy.FAIL:冲突策略是事务失败。 5. OnConflictStrategy.IGNORE:冲突策略是忽略冲突。 */ @Insert(onConflict = OnConflictStrategy.REPLACE) fun addUsers(users: List<User>) //更新用户 @Update fun updateUsers(users: List<User>) //删除用户 @Delete fun deleteUser(user: User) //根据条件删除用户 @Query("delete from user where id = :id") fun deleteUserById(id: Long) }
4、创建 Database 单例数据库 @Database(entities = [User::class], version = 2) abstract class AppDatabase : RoomDatabase() { abstract fun userDao(): UserDao companion object { private var instance: AppDatabase? = null fun getInstance(context: Context): AppDatabase { if (instance == null) { instance = Room.databaseBuilder( context.applicationContext, AppDatabase::class.java, "data.db" ).allowMainThreadQueries() .build() } return instance as AppDatabase } } }
5、使用 val users = listOf( User(1, "张三", 20, true, "123456","45454"), User(2, "李四", 22, true, "123456","45454") ) AppDatabase.getInstance(this).userDao().addUsers(users) var userList = AppDatabase.getInstance(this) .userDao() .getUsers()
6、数据库升级 1、修改版本号
2、调用addMigrations方法,其中Migration需要两个参数,startVersion表示的是升级开始的版本,endVersion表示要升级到的版本。同时需要将@Database注解中的version的值修改为和endVersion相同。
@Database(entities = [User::class], version = 2) abstract class AppDatabase : RoomDatabase() { abstract fun userDao(): UserDao companion object { private var instance: AppDatabase? = null fun getInstance(context: Context): AppDatabase { if (instance == null) { instance = Room.databaseBuilder( context.applicationContext, AppDatabase::class.java, "data.db" ).allowMainThreadQueries() .addMigrations(object : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL("ALTER TABLE User ADD COLUMN mobile TEXT NOT NULL DEFAULT 10") } }) .build() } return instance as AppDatabase } } }