一、前言

Room 是 Android Jetpack 的一部分。在 Android 中数据库是SQLite数据库,Room 就是在SQLite上面提供了一个抽象层,通过 Room 既能流畅地访问数据库,又能充分展示 SQLite 数据库的强大功能。Room 主要有以下几大优点:

  • 在编译时校验 SQL 语句;
  • 易用的注解减少重复和易错的模板代码;
  • 简化的数据库迁移路径。

正是 Room 有以上的优点,所以建议使用 Room 访问数据库。

二、Room 主要组件

Room 主要组件有三个:

  • 数据库类(RoomDatabase):拥有数据库,并作为应用底层持久性数据的主要访问接入点。
  • 数据实体类(Entity):表示应用数据库中的表。
  • 数据访问对象(DAO):提供方法使得应用能够在数据库中查询、更新、插入以及删除数据。

应用从数据库类获取一个与之相关联的数据访问对象(DAO)。应用可以通过这个数据访问对象(DAO)在数据库中检索数据,并以相关联的数据实体对象呈现结果;应用也可以使用对的数据实体类对象,更新数据库对应表中的行(或者插入新行)。应用对数据库的操作完全通过 Room 这个抽象层实现,无需直接操作 SQLite数据库。下图就是 Room 各个组件之间的关系图:

三、Room 基础入门

大致了解了 Room 的工作原理之后,下面我们就来介绍一下 Room 的使用入门。

3.1 引入 Room 库到项目

引入 Room 库到项目,在项目程序模块下的 build.gradle 文件的 dependencies

// Kotlin 开发环境,需要引入 kotlin-kapt 插件
apply plugin: 'kotlin-kapt'// .........dependencies {// other dependecies def room_version = "2.3.0"implementation("androidx.room:room-runtime:$room_version")// 使用 Kotlin 注解处理工具(kapt,如果项目使用Kotlin语言开发,这个必须引入,并且需要引入 kotlin-kapt 插件kapt("androidx.room:room-compiler:$room_version")// To use Kotlin Symbolic Processing (KSP)// ksp("androidx.room:room-compiler:$room_version")// 可选 - 为 Room 添加 Kotlin 扩展和协程支持implementation("androidx.room:room-ktx:$room_version")// 可选 - 为 Room 添加 RxJava2 支持implementation "androidx.room:room-rxjava2:$room_version"// 可选 - 为 Room 添加 RxJava3 支持implementation "androidx.room:room-rxjava3:$room_version"// optional - Guava support for Room, including Optional and ListenableFutureimplementation "androidx.room:room-guava:$room_version"// optional - Test helperstestImplementation("androidx.room:room-testing:$room_version")
}

注意事项:如果项目是用 kotlin 语言开发,一定要引入 kotlin 注解处理工具,并且在 build.gradle 中添加 kitlin-kapt插件(apply plugin: 'kotlin-kapt'),否则应用运行会抛出 xx.AppDatabase. AppDatabase_Impl does not exist 异常。

3.2 Room 使用示例

使用 Room 访问数据库,需要首先定义 Room 的三个组件,然后通过数据访问对象实例访问数据。

3.2.1 定义数据实体类

数据实体类对应数据库中的表,实体类的字段对应表中的列。定义 Room 数据实体类,使用 data class 关键字,并使用 @Entity 注解标注。更多关于数据实体类相关注解(包括属性相关注解),请参考: Android Room 数据实体类详解。如下代码所示:

@Entity
class User(@PrimaryKey val uid: Int, @ColumnInfo() val name: String, @ColumnInfo val age: Int)

注意事项:默认情况下,Room 会根据实体类的类为表名(在数据库中表名其实不区分大小写),开发者也可以在 @Entity 注解通过 tableName 参数指定表名。

3.3.2 定义数据访问对象(DAO)

数据访问对象是访问数据库的桥梁,通过 DAO 访问数据,查询或者更新数据库中的数据(数据实体类是媒介)。数据访问对象(DAO)是一个接口,定义时添加 @Dao 注解标注,接口中的每一个成员方法表示一个操作,成员方法使用注解标示操作类型。更多关于数据访问对象(DAO)和数据操作类型注解,请参考:Android Room 数据访问对象详解。以下是简单的 DAO 示例代码:

@Dao
interface UserDao {@Query("SELECT * FROM user")fun getAll(): List<User>@Query("SELECT * FROM user WHERE name LIKE :name")fun findByName(name: String): List<User>@Insertfun insertAll(vararg users: User)@Deletefun delete(user: User)
}

注意事项:
1. 数据访问对象是接口类型,成员方法是没有方法体的,成员方法必须使用注解标示操作类型;
2. 数据库实体类成员方法中的 SQL 语句,在编译是会检查语法是否正确。

3.3.3 定义数据库类

数据库是存储数据的地方,使用 Room 定义数据库时,声明一个抽象类(abstract class),并用 @Database 注解标示,在 @Database 注解中使用 entities 参数指定数据库关联的数据实体类列表,使用 version 参数指定数据的版本。数据库类中包含获取数据访问实体类对象的抽象方法,更多关于数据库相关内容,请参考:Android Room 数据库详解,以下是简单的数据类定义。

@Database(entities = [User::class], version = 1)
abstract class AppDatabase: RoomDatabase() {abstract fun userDao(): UserDao
}

注意事项:
1. 数据库类是一个抽象类,他的成员方法是抽象方法;
2. 定义数据库类时必须指定关联的数据实体类列表,这样数据库类才知道需要创建那些表;
3. 数据的版本号,如果数据库的表构造有变动时,需要升级版本号,这样数据库才会更新表结构(如修改表字段、新增表等,跟直接使用 SQLite 接口使用 SQLiteDatabase 类一样),但是数据库的升级并不是修改版本号那么简单,还需要处理数据库升级过程中需要修改的地方,更多详情请参考:Android Room 数据库升级。

3.3.4 创建数据库实例

定义好数据实体类、数据访问对象(DAO)和数据类之后,便可以创建数据库实例。使用 Room.databaseBuilder().build() 创建一个数据库实体类,Room 会根据定义的数据实体类、数据库访问对象和数据库类,以及他们定义时指定的对应关系,自动创建数据库和对应的表关系。如以下示例代码所示:

val db = Room.databaseBuilder(applicationContext, AppDatabase::class.java, "app_db").build()

注意事项:
1. 每一个 RoomDatabase 实例都是非常耗费资源的,如果你的应用是单个进程中运行,那么在实例 RoomDatabase 时请遵循单例设计模式,在单个进程中几乎不需要访问多个 RoomDatabase 实例。
2. 如果你的应用在多个进程中运行(比如:远程服务(RemoteService)),在构建 RoomDatabase 的构建器中调用 Room.databaseBuilder().enableMultiInstanceInvalidation() 方法,这样一来,在每个进程中都有一个 RoomDatabase 实例,如果在某个进程中将共享的数据库文件失效,将会自动将这个失效自动同步给其他进程中的 RoomDatabase 实例。

3.3.5 从数据库实例中获取数据访问对象(DAO)实例

在定义数据库类时,将数据访问对象(DAO)类与之相关联,定义抽象方法返回对应的数据库访问对象(DAO)实例。在数据库实例化过程中,Room 会自动生成对应的数据访问对象(DAO),只需要调用定义数据库类时定义的抽象方法,即可获取对应的数据访问对象(DAO)实例。如下示例所示:

val userDao = db.userDao()

3.3.6 通过数据访问对象(DAO)实例操作数据库

获取到数据访问对象(DAO)实例,就可以调用数据库访问对象(DAO)类中定义的方法操作数据库了。如下示例所示:

Thread {// 插入数据userDao.insertAll(User(1, "Student1", 18), User(2, "Student2", 18),User(3, "Student3", 17), User(4, "Student4", 19))// 查询数据val result = userDao.getAll()result.forEach {println("Student: id = ${it.uid}, name = ${it.name}, age = ${it.age}")}
}.start()

注意事项:
1. 使用数据访问对象(DAO)实例操作数据库时,不能再 UI 主线程中调用 DAO 接口,否则会抛出异常(java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.

四、编后语

Room 是非常强大易用的,可以减少数据库操作过程中的出错,因为所有的 SQL 语句都在编译是进行检查,如果存在错误,将会在编译时就显示错误信息。不仅如此,Room 还非常优秀地处理了多进程很多线程访问数据库的问题。下面是关于 Room 使用的进阶博文:

  1. Android Room 数据实体类详解
  2. Android Room 数据访问对象(DAO)详解
  3. Android Room 数据库详解
  4. 在 Room 数据库中创建视图
  5. 使用单元测试测试您的 Room 数据库

Android Room 库基础入门相关推荐

  1. MySQL---数据库基础入门

    MySQL---数据库基础入门 作者:qq_26525215 从最开始的创建数据库,创建表,创建列开始写起,再到常用的EXISTS函数,SELECT 复杂查询,模糊查询LIKE,创建视图 等深入学习. ...

  2. Android App Bundle基础入门

    一.前言 重要提示:从 2021 年 8 月起,新应用需要使用 Android App Bundle 才能在 Google Play 中发布.现在,Play Feature Delivery 或 Pl ...

  3. rxjava面试题,android教程零基础入门

    网易游戏 严格来说我投的是网易互娱(区别于雷火&盘古,后面再说更多区别),走的内推.网易游戏以其笔试难度大著名,这次也不例外:所有的内推都要求参加统一笔试,我记得笔试有几场,我是在第一场.内推 ...

  4. 用Python画一只溜达小狗——turtle库基础入门

    一只脑门有点方的小狗,其实还可以把脑门和后脑勺完善一下,更圆润一些. 但这样也挺可爱,就保有这样不完美但独一无二的它吧.绘制过程主要就是拼接和调整圆弧,尽量做到过度自然. 小狗的绘制主要使用了turt ...

  5. Android 音频开发(一) 基础入门篇

    今天主要讲解下Android音频开发的入门知识,希望对想入门却不知如何下手的朋友有所帮助,同时希望能得到高手的指点和帮助. 深入细化基础技能知识点 大致细化如下10个知识点. 音频开发的主要应用有哪些 ...

  6. Android Studio新手–下载安装配置–零基础入门–基本使用–调试技能–构建项目基础–使用AS应对常规应用开发

    转自:http://blog.csdn.net/yanbober/article/details/45306483 目标:Android Studio新手–>下载安装配置–>零基础入门–& ...

  7. Android基础入门视频培训教程-刘志远-专题视频课程

    Android基础入门视频培训教程-146257人已学习 课程介绍         Android基础入门视频培训课程,该教程内容涵盖Android入门开发基本技能(环境搭建.Lineralayout ...

  8. Android基础入门教程——1.1 背景相关与系统架构分析

    Android基础入门教程--1.1 背景相关与系统架构分析 标签: Android基础入门教程 1.Android背景与当前的状况 Android系统是由Andy Rubin创建的,后来被Googl ...

  9. 学Android移动开发 第1章 Android基础入门

    文章目录 1.1 Android简介 什么是Android Android和iOS主要区别 1.1.1 通信技术 1.1.2 Android起源 1.1.3 Android体系结构 1.1.4 Dal ...

  10. Android Studio 基础入门笔记

    Android Studio 基础入门笔记 Android Studio 基础入门笔记 为什么选择使用 Android Studio 而不是EclipseADT 安卓配置JDK AS如何更新 常规的 ...

最新文章

  1. 显示域用户登录的ip或计算机名,如何在使用PowerShell脚本或者VBS脚本,查看域内正在登录的域用户名、主机名和主机IP地址...
  2. Mac模拟慢速网络 - Network Link Conditioner 安装和使用
  3. PyCharm调试错误
  4. 字符串获取类、封装检测数字的方法
  5. 浅谈ajax中get与post的区别,以及ajax中的乱码问题的解决方法
  6. 【Flink】Flink Recovered containers from previous attempts
  7. 使用MMS(MongoDB Monitoring Service)监控MongoDB
  8. Unity 中 Png转Texture2D再转Sprite
  9. java方法重载和重载方法_Java中的重载与重载
  10. NAT模式和桥接模式的区别详解
  11. 我的世界如何制作一个空岛服务器,我的世界1.7.10 God 世界空岛服务器
  12. 微信网页授权多应用多域名使用 oauth2授权
  13. 云服务器配置java环境
  14. Pandas:1.创建、读和写操作
  15. Linux系统目录管理
  16. android界面设计的解剖,ps cc 2017启动画面的制作解剖
  17. 摩拜ofo补贴战熄火 月卡大涨价网店打折卖
  18. uni-app中使用unicloud短信验证码(开通、模板报备、使用)
  19. 单片机c语言程序开发洗衣机,基于51单片机的洗衣机程序
  20. 云和恩墨全面助力某快递公司 即时保障业务系统持续高效运行

热门文章

  1. 酪氨酸激酶的抑制剂——白血病的靶向研究
  2. MySQL5.6 GTID
  3. iOS音乐播放器实现日记
  4. 基于vue-router的matched实现面包屑功能
  5. android 自定义locale,关于android:设置Locale.setDefault(locale)后,如何获取手机语言?...
  6. java并发编程第十二课 java内存模型
  7. 神仙项目,轻松上手了解前后端分离!
  8. 云计算是什么?3分钟了解云计算技术
  9. 中科院NIPS 2017论文提出深度离散哈希算法,可用于图像检索:Deep Supervised Discrete Hashing
  10. 李宏毅ML2021 HW3创建pseudo dataset