初探Architecture Components之Room

本文介绍了Google的Android持久化库Room,它旨在简化SQLite数据库的使用,减少样板代码并提供编译时的错误检查。文章讨论了Room的初衷,其带来的好处,如避免模板代码和在编译时验证SQL语句。还详细阐述了Room的配置,包括Gradle依赖,以及其主要组成部分:Database、Entity和DAO。接着,展示了如何在Kotlin中创建和使用Room数据库,包括数据的增删改查操作。最后,提到了Room对RxJava的支持,返回Cursor对象的可能性,多表查询,以及数据库迁移和遇到的一些坑。
摘要由CSDN通过智能技术生成

官方文档:Room Persistence Library

Room的初衷

提起SQLite,作为Android开发者还是比较幸福的的,Android核心框架已为处理SQL提供了相当大的支持,API也非常强大,省起来很大的力气。但是其模板化处理方式,导致开发者花费大量的时间和精力去维护数据库:

  • 在编译时,没有对原始SQL查询语句验证。随着表结构的更改,需要手动更新SQL查询语句。这个过程不仅耗时耗精力,而且很容易出错。
  • 需要使用大量的样板代码执行SQL操作和Java数据对象之间的转换。

正因为这些原因,一批大神造轮子,开源了很多优秀的开源框架,比如GreenDao、OrmLite、Active Android等等,给我们带来了十分的便利。
这里给大家推荐另外一个开源框架 - Room,其作者是Android的爹Google。既然是Google出品,我想有必要学习一下。

Room给我们带来了什么样的惊喜呢?

  1. 避免了样板间似的代码块。
  2. 能轻松的将SQLite表数据转换为Java对象
  3. Room提供了编译SQLite语句时检查,避免了SQL语句在执行时,才发现错误
  4. 可以返回RxJava的Flowable和LiveData的可观察实例,对SQLite的异步操作提供强力支持。

Gradle配置

在buildl.gradle里面添加依赖即可:

  • compile “android.arch.persistence.room:runtime:1.0.0-alpha1”
  • annotationProcessor “android.arch.persistence.room:compiler:1.0.0-alpha1”

Room对RxJava 2是完美支持, 如果习惯了RxJava异步操作的,可以添加RxJava支持库:

  • compile “android.arch.persistence.room:rxjava2:1.0.0-alpha1”

Room的三大组成部分

  • Database(数据库):使用此组件创建数据库Holder。
    • 通过注解实体类定义表结构,该实体类的实例即为数据库中的数据访问对象(在Dao内操作)。
    • 它是链接SQL底层的主要接入点。
    • 注解的类必须是继承于RoomDatabase的抽象类
    • 在运行时,可以通过调用Room.databaseBuilder()或Room.inMemoryDatabaseBuilder()获取其实例
  • Entity(实体类):该组件表示持有一个表的字段(即数据库一行的数据)的实体类。

    • 对于每个实体,创建一个数据库表来保存它们。
    • 必须通过Database类中的Entity数组引用实体类
    • 实体类的每个字段都会保存数据库的表中。如果不想保存某字段,该字段需使用@Ignore注解

    如果Dao类可以访问每个持久化的字段(即表中的字段),实体可以有一个空构造函数。当然,该实体类还可以有一个构造函数,其参数应包含与实体中的字段相匹配的类型和名称。Room可以使用含有全部字段或者部分字段的构造函数,例如只含有部分字段的构造函数??????

  • DAO(抽象类/接口):该组件表示作为数据访问对象(DAO即为Data Access Object的简写)的类或者接口。

    • DAO是Room的主要组件,负责定义访问数据库的方法。
    • 该抽象类或接口使用@Database注解,同时必须含有一个无参数的抽象方法,并返回@Dao注解的实际操作类。
    • 在编译时,Room创建这个抽象类或接口的实现。

    注意:通过使用DAO类访问数据库,而不是使用查询构建器或直接查询,可以将数据库体系结构的不同组件分离。另外,在测试应用程序时,DAO可以轻松的模拟数据库访问。

  • Room与应用程序的架构体系

    简单使用

    现在已经对Room库有了初步的认识,下面我们来看看Room库在应用程序中,怎么应用的呢?

    1. 创建实体类-UserEntity,使用@Entity注解,将其作为数据库中的一个表的实体

      @Entity(tableName = "user")
      data class UserEntity (@PrimaryKey @ColumnInfo(name = "id")val id: Int,
                                        @ColumnInfo(name = "name")val name: String,
                                        @ColumnInfo(name = "is_brrowed")val isBrrowed: Int)
      
    2. 声明抽象类AppDatabase,继承于RoomDatabase,该类使用@Database注解,用于为应用程序创建一个数据库

      @Database(entities = arrayOf(UserEntity::class), version = 1)
      abstract class AppDatabase: RoomDatabase() {
      
      }
      


      请注意:

      • 在Kotlin中,entities注解参数为vararg参数传递时,必须将参数的显示的的声明为arrayOf()。
      • 在编译时,由Room库对AppDatabase实现,我们不需多做处理。
    3. 创建数据库访问对象(DAO), 用于访问数据库

      @Dao
      interface UserDao {
          // 向表中插入一系列
          @Insert(onConflict = OnConflictStrategy.REPLACE)
          fun insertUser(vararg user: UserEntity)
      
          @Insert
          fun insertUser(users: List<UserEntity>)
      
          ***
      }
      
    4. 在AppDatabase引用UserDao,就是在AppDatabase中声明一个抽象方法,返回UserDao实例。

      @Database(entities = arrayOf(UserEntity::class), version = 1)
      abstract class AppDatabase : RoomDatabase() {
      
          abstract fun userDao(): UserDao
      }
      
    5. 创建数据库,像数据库添加数据后,并查询。

      class RoomActivity : BaseActivity() {
      
          ***
      
          @SuppressLint("StaticFieldLeak")
          override fun setListener() {
              acb_create.setOnClickListener {
                  doAsync {
                      applicationContext.deleteDatabase(DATABASE_NAME)
      
                      mDataBase = Room.databaseBuilder(applicationContext,
                              AppDatabase::class.java, DATABASE_NAME).build()
                  }
              }
      
              acb_insert.setOnClickListener {
                  doAsync {
                      val users: MutableList<UserEntity> = mutableListOf()
      
                      (0..10).mapTo(users) {
                          val user = UserEntity(id, "Test - it", id % 2)
                          id++
                          user
                      }
      
                      mDataBase?.beginTransaction()
      
                      try {
                          mDataBase?.userDao()?.insertUser(users)
                          mDataBase?.setTransactionSuccessful()
                      } finally {
                          mDataBase?.endTransaction()
                      }
                  }
              }
      
              ***
      
              acb_query.s
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值