Android Room 库基础入门
一、前言
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 使用的进阶博文:
- Android Room 数据实体类详解
- Android Room 数据访问对象(DAO)详解
- Android Room 数据库详解
- 在 Room 数据库中创建视图
- 使用单元测试测试您的 Room 数据库
Android Room 库基础入门相关推荐
- MySQL---数据库基础入门
MySQL---数据库基础入门 作者:qq_26525215 从最开始的创建数据库,创建表,创建列开始写起,再到常用的EXISTS函数,SELECT 复杂查询,模糊查询LIKE,创建视图 等深入学习. ...
- Android App Bundle基础入门
一.前言 重要提示:从 2021 年 8 月起,新应用需要使用 Android App Bundle 才能在 Google Play 中发布.现在,Play Feature Delivery 或 Pl ...
- rxjava面试题,android教程零基础入门
网易游戏 严格来说我投的是网易互娱(区别于雷火&盘古,后面再说更多区别),走的内推.网易游戏以其笔试难度大著名,这次也不例外:所有的内推都要求参加统一笔试,我记得笔试有几场,我是在第一场.内推 ...
- 用Python画一只溜达小狗——turtle库基础入门
一只脑门有点方的小狗,其实还可以把脑门和后脑勺完善一下,更圆润一些. 但这样也挺可爱,就保有这样不完美但独一无二的它吧.绘制过程主要就是拼接和调整圆弧,尽量做到过度自然. 小狗的绘制主要使用了turt ...
- Android 音频开发(一) 基础入门篇
今天主要讲解下Android音频开发的入门知识,希望对想入门却不知如何下手的朋友有所帮助,同时希望能得到高手的指点和帮助. 深入细化基础技能知识点 大致细化如下10个知识点. 音频开发的主要应用有哪些 ...
- Android Studio新手–下载安装配置–零基础入门–基本使用–调试技能–构建项目基础–使用AS应对常规应用开发
转自:http://blog.csdn.net/yanbober/article/details/45306483 目标:Android Studio新手–>下载安装配置–>零基础入门–& ...
- Android基础入门视频培训教程-刘志远-专题视频课程
Android基础入门视频培训教程-146257人已学习 课程介绍 Android基础入门视频培训课程,该教程内容涵盖Android入门开发基本技能(环境搭建.Lineralayout ...
- Android基础入门教程——1.1 背景相关与系统架构分析
Android基础入门教程--1.1 背景相关与系统架构分析 标签: Android基础入门教程 1.Android背景与当前的状况 Android系统是由Andy Rubin创建的,后来被Googl ...
- 学Android移动开发 第1章 Android基础入门
文章目录 1.1 Android简介 什么是Android Android和iOS主要区别 1.1.1 通信技术 1.1.2 Android起源 1.1.3 Android体系结构 1.1.4 Dal ...
- Android Studio 基础入门笔记
Android Studio 基础入门笔记 Android Studio 基础入门笔记 为什么选择使用 Android Studio 而不是EclipseADT 安卓配置JDK AS如何更新 常规的 ...
最新文章
- 显示域用户登录的ip或计算机名,如何在使用PowerShell脚本或者VBS脚本,查看域内正在登录的域用户名、主机名和主机IP地址...
- Mac模拟慢速网络 - Network Link Conditioner 安装和使用
- PyCharm调试错误
- 字符串获取类、封装检测数字的方法
- 浅谈ajax中get与post的区别,以及ajax中的乱码问题的解决方法
- 【Flink】Flink Recovered containers from previous attempts
- 使用MMS(MongoDB Monitoring Service)监控MongoDB
- Unity 中 Png转Texture2D再转Sprite
- java方法重载和重载方法_Java中的重载与重载
- NAT模式和桥接模式的区别详解
- 我的世界如何制作一个空岛服务器,我的世界1.7.10 God 世界空岛服务器
- 微信网页授权多应用多域名使用 oauth2授权
- 云服务器配置java环境
- Pandas:1.创建、读和写操作
- Linux系统目录管理
- android界面设计的解剖,ps cc 2017启动画面的制作解剖
- 摩拜ofo补贴战熄火 月卡大涨价网店打折卖
- uni-app中使用unicloud短信验证码(开通、模板报备、使用)
- 单片机c语言程序开发洗衣机,基于51单片机的洗衣机程序
- 云和恩墨全面助力某快递公司 即时保障业务系统持续高效运行
热门文章
- 酪氨酸激酶的抑制剂——白血病的靶向研究
- MySQL5.6 GTID
- iOS音乐播放器实现日记
- 基于vue-router的matched实现面包屑功能
- android 自定义locale,关于android:设置Locale.setDefault(locale)后,如何获取手机语言?...
- java并发编程第十二课 java内存模型
- 神仙项目,轻松上手了解前后端分离!
- 云计算是什么?3分钟了解云计算技术
- 中科院NIPS 2017论文提出深度离散哈希算法,可用于图像检索:Deep Supervised Discrete Hashing
- 李宏毅ML2021 HW3创建pseudo dataset