你若需要时间,还得自己把他造出来。 喝汤能补 (* ^ ▽ ^ *)
前言
该文章作为学习交流,如有错误欢迎各位大佬指正 (* ^ ▽ ^ *)
- 本文简介
主要讲解:Room的使用,以及相关API的使用。
概述
Room是Android官方推出的一个ORM框架,并是JetPack的组件之一。
作用是:使用ORM框架,将SQlite数据库最原始的API进行封装,方便使用,避免因原始API方法的变动导致项目代码发送混乱。
- ORM(也称对象关系映射),Kotlin编程语言是面向对象语言,而使用的数据库则是关系型数据库,将面向对象的语言和面向关系的数据库之间建立一种映射关系,就是ORM。作用:可以用面向对象的思维与数据库进行交互,绝大数情况下不用与SQL语句进行交互,也无需担心操作数据库的逻辑会让项目整体代码混乱。
Room主要有Entity、Dao、Database 3个部分组成。
- Entity:用于定义封装实际数据的实体类,每个实体类都会在数据库中有一张对应的表,并且表中的列是根据实体类中字段自动生成的。
- Dao:Dao是数据访问对象的意思,通常会在这里对数据库的各项操作进行封装,在实际编程的时候,逻辑层就不需要和底层数据库进行交互了,直接和Dao层进行交互即可。
- Insert,Update,Delete,Query分别对应插入,更新,删除,查询四种数据库操作。其中,Query需要编写查询的SQL语句,其他不用。使用非实体类参数进行增删改数据时,也要编写SQL语句,并且都使用Query注解,不能使用insert,update,delete注解。
- Database:用于定义数据库中的关键信息,包括数据库的版本号,包含哪些实体类以及提供Dao层的访问实例。定义的类必须是抽象的,同时该类中的实体方法也需要是抽象的,具体实现Room在底层自动完成。 Database示例的创建方法Room.databaseBuilder
Room.databaseBuilder(applicationContext,自定义DataBase::class.java,"数据库名称")
.allowMainThreadQueries()
.fallbackToDestructiveMigration()
.build().apply {
instance = this
}
第一个参数:一定要applicationContext,普通的context会导致内存泄漏情况。
第二个参数:自定义的DataBase的class类型
第三个参数:数据库名称
build()方法完成构建
allowMainThreadQueries() 该方法表示允许在主线程中进行数据库操作。一般在测试环境下使用
fallbackToDestructiveMigration()方法,表示只要进行升级,则Room将当前数据库销毁,然后再重新创建,缺点是:之前数据库中的所有数据全部丢失。
- 数据库操作属于耗时操作,Room默认是不允许在主线程中进行数据库操作的,所以需要将这些增删查改的操作放到子线程中
- 数据库升级,先修改@Database(version = 2…) 中version的版本号,根据升级前后的数据库的版本号,以及升级的数据库的逻辑SQL创建Migration 实例。然后在DataBase的Build构建中调用addMigrations(Migration实例)方法执行数据库升级的逻辑。
// 修改@Database(version = 2, entities = [User::class,Book::class]) 中的version版本号为最新的版本号
val MIGRATION_1_2 = object : Migration(1,2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("Create Table Book (id integer primary key autoincrement " +
"not null, name text not null, pages integer not null)")
}
}
Room.databaseBuilder(context.applicationContext,
LibraryDataBase::class.java,"library_database")
.allowMainThreadQueries()
.addMigrations(MIGRATION_1_2)
.build().apply {
instance = this
}
使用
依赖库
在app/build.gradle文件中添加依赖。
首先增加一个kotlin-kapt插件,然后dependencies 中引入依赖库。其中kapt引入的是编译时注解库。
- 扩展,Java项目,使用annotationProcessor而不是kapt
apply plugin: 'kotlin-kapt'
android {
//...
}
dependencies {
//...
implementation "androidx.room:room-runtime:2.2.5"
kapt "androidx.room:room-compiler:2.2.5"
}
增删查改
首先,使用 @Entity 创建基本的实体类User。使用 @Dao 创建数据库的操作类。最后使用 @Database 创建出数据库的版本号,包含实体,以及Dao层的访问实例。
简单例子
功能是,编写基本的增,删,查,改操作的方法,实体类是User,在Dao中编写增加两个User,更新User的年龄,删除User,查询所有的用户
@Entity //声明实体类
data class User(var name: String, var age: Int) {
@PrimaryKey(autoGenerate = true) //设置主键,autoGenerate 自动生成属性
var id: Long = 0
}
@Dao
interface UserDao {
@Insert //插入完成后,自动生成主键id返回
fun insertUser(user: User): Long
@Update //传入User对象会更新到数据库中
fun updateUser(newUser: User)
@Query("select * from User")
fun loadAllUsers(): List<User>
@Query("select * from User where age > :age")
fun loadUsersOlderThan(age: Int): List<User>
@Delete //删除传入的User对象
fun deleteUser(user: User)
@Query("delete from User where name = :name")
fun deleteUserByName(name: String): Int
}
@Database(version = 1, entities = [User::class])
abstract class LibraryDataBase : RoomDatabase(){
//这里的获取Dao实例方法,只需要定义抽象的声明即可,具体实现Room在底层自动完成
abstract fun userDao(): UserDao
companion object { //单例
private var instance: LibraryDataBase? = null
@Synchronized
fun getDatabase(context: Context): LibraryDataBase{
instance?.let {
return it
}
return Room.databaseBuilder(context.applicationContext,
LibraryDataBase::class.java,"library_database")
.build().apply {
instance = this
}
}
}
}
数据库升级
如果是在测试阶段,可以通过在DataBase的Build构建中增加fallbackToDestructiveMigration()方法,表示只要进行升级,则Room将当前数据库销毁,然后再重新创建,缺点是:之前数据库中的所有数据全部丢失。
简单例子
功能:从数据库版本1到2增加了Book表,数据库版本2到3使用alter语句增加了Book的列
@Entity
data class Book(var name: String, var pages: Int) {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}
@Dao
interface BookDao {
@Insert
fun insertBook(book: Book): Long
@Query("select * from Book")
fun loadAllBooks(): List<Book>
}
@Database(version = 3, entities = [User::class,Book::class])
abstract class LibraryDataBase : RoomDatabase(){
abstract fun userDao(): UserDao //这里的获取Dao实例方法,只需要定义抽象的声明即可,具体实现Room在底层自动完成
abstract fun bookDao(): BookDao
companion object { //单例
private var instance: LibraryDataBase? = null
val MIGRATION_1_2 = object : Migration(1,2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("Create Table Book (id integer primary key autoincrement " +
"not null, name text not null, pages integer not null)")
}
}
val MIGRATION_2_3 = object : Migration(2,3){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("alter table Book add column author text not null default 'unknown'")
}
}
@Synchronized
fun getDatabase(context: Context): LibraryDataBase{
instance?.let {
return it
}
return Room.databaseBuilder(context.applicationContext,
LibraryDataBase::class.java,"library_database")
.allowMainThreadQueries()
.addMigrations(MIGRATION_1_2,MIGRATION_2_3)
.build().apply {
instance = this
}
}
}
}
觉得有帮助的点下赞哟,毕竟三连步骤更多,嘻嘻,谢谢大家的支持(* ^ ▽ ^ *)