Android(Kotlin)Jetpack组件之Room使用与API

你若需要时间,还得自己把他造出来。 喝汤能补 (* ^ ▽ ^ *)

前言

  该文章作为学习交流,如有错误欢迎各位大佬指正 (* ^ ▽ ^ *)

  • 本文简介
    主要讲解:Room的使用,以及相关API的使用。

概述

  Room是Android官方推出的一个ORM框架,并是JetPack的组件之一。
作用是:使用ORM框架,将SQlite数据库最原始的API进行封装,方便使用,避免因原始API方法的变动导致项目代码发送混乱。

  • ORM(也称对象关系映射),Kotlin编程语言是面向对象语言,而使用的数据库则是关系型数据库,将面向对象的语言和面向关系的数据库之间建立一种映射关系,就是ORM。作用:可以用面向对象的思维与数据库进行交互,绝大数情况下不用与SQL语句进行交互,也无需担心操作数据库的逻辑会让项目整体代码混乱。

  Room主要有Entity、Dao、Database 3个部分组成。

  • Entity:用于定义封装实际数据的实体类,每个实体类都会在数据库中有一张对应的表,并且表中的列是根据实体类中字段自动生成的。
  • Dao:Dao是数据访问对象的意思,通常会在这里对数据库的各项操作进行封装,在实际编程的时候,逻辑层就不需要和底层数据库进行交互了,直接和Dao层进行交互即可。
  • InsertUpdateDeleteQuery分别对应插入,更新,删除,查询四种数据库操作。其中,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
                }
        }
    }
}

觉得有帮助的点下赞哟,毕竟三连步骤更多,嘻嘻,谢谢大家的支持(* ^ ▽ ^ *)

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值