Android Room Library 简单使用

2024-02-28 12:08

本文主要是介绍Android Room Library 简单使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Room 的一些特点

  1. 编译时 sql 语句检查。相信大家都有过 app 跑起来,执行到 db 语句的时候 crash,检查之后发现原来是 sql 语句少了一个 ) 或者其它符号之类的经历。Room 会在编译阶段检查你的 DAO 中的 sql 语句,如果写错了(包括 sql 语法错误跟表名、字段名等等错误),会直接编译失败并提醒你哪里不对。
  2. sql 查询直接关联到 Java 对象。这个应该不用详细解释了,虽然很多第三方 db 库早已经实现。
  3. 耗时操作主动要求异步处理。这一点还是挺值得注意的,Room 会在执行 db 操作时判断是不是在 UI 线程,比如当你需要插入一条记录到数据库时,Room 会让你放到异步线程去做,否则会直接 crash 掉 app 来告诉你不这样做容易阻塞 UI 线程。虽说死相难看了点(个人觉得打个警告不就完了么?),但对于开发者开发出高质量的应用还是有帮助的。
  4. 基于注解编译时自动生成代码。这个应该算是 Room 工作原理的核心所在了,你要写的代码之所以这么少,说白了还不是因为 Google 给你写好了很多?希望以后有时间能写一篇源码分析出来,那个时候再讲吧。
  5. API 设计符合 Sql 标准。方便扩展进行各种 db 操作。

Room 的三大组件

  • Entity。实体,说白了就是我们最常见的一个对象
  • Database。数据库,Room 提供了一个非常方便的静态方法来供我们创建数据库
  • DAO。Data Access Object,把你 Entity 所有的 CRUD 业务代码封装在这里就好

开始使用

Room 的用法,说白了就是创建上面的三大组件,写完了,剩下的交给 Google 就好。

  • 创建一个实体类 UserEntity.java
@Entity(tableName = "user")
public class UserEntity {@PrimaryKey(autoGenerate = true)private int _id;private String name;private String age;public int get_id() {return _id;}public void set_id(int _id) {this._id = _id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public UserEntity(String name, String age) {this.name = name;this.age = age;}
}

划重点:

  1. 顶部使用 @Entity(tableName = "user") 声明这是一个实体类。其中,tableName 如果不写,那么默认类名就是表名。因为我不想创建出来的表名叫 UserEntity,所以我声明了表名叫 user
  2. 属性使用 @PrimaryKey(autoGenerate = true) 声明这是一个主键。其中,autoGenerate = true 代表自动生成,而且会随着数据增加自增长,可以理解成就是 AUTOINCRESEMENT

  3. 创建实体操作接口类 UserEntityDao.java

@Dao
public interface UserEntityDao {@Query("select * FROM User")List getUserList();@Query("select * FROM User WHERE name = :name")UserEntity getUserByName(String name);@Insert(onConflict = OnConflictStrategy.REPLACE)void addUser(UserEntity userEntity);@Delete()void deleteUser(UserEntity userEntity);}

划重点: 1. 顶部使用 @Dao 声明这是 DAO,就是这么简单。 2. CRUD 操作全部使用注解声明,需要具体 sql 语句的,直接在注解里书写就好。具体支持哪些操作可以去 android.arch.persistence.room 包下面查看,我这边就随便写了几个。注意,Room会在编译时检查你的 sql 语句,如果有语法错误,或者表名、字段名错误,都会直接编译报错让你修改,避免运行时出现 crash。 3. 你问我这些接口的实现在哪?答案是:Google 会帮你搞定。是的,你只需要写这些就可以了。

  • 创建数据库抽象类 AppDatabase.java
@Database(entities = {UserEntity.class}, version = 2, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {private static AppDatabase sInstance;public static AppDatabase getDatabase(Context context) {if (sInstance == null) {sInstance = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class,"user.db").build();}return sInstance;}public static void onDestroy() {sInstance = null;}public abstract UserEntityDao getUserEntityDao();}

划重点: 1. 顶部使用 @Database 声明这是一个数据库类,其中 entities里面声明你的数据库里究竟包含了哪几个实体;version 就不用我说了吧,写过 SqliteOpenHelper 的肯定不陌生了;第三个属性 exportSchema 比较有意思,Google 建议是传 true,这样可以把 Scheme 导出到一个文件夹里面,Google 还建议你把这个文件上传到 VCS,具体的可以直接点进去看注释。 2. 这个类封装成单例,在任何地方需要执行数据库操作的时候,可以直接获得来使用,Room 提供了一个静态的方法,用来在默认的构造方法里创建了一个数据库,我在这里起的名称是 user.db。 3. 把所有 Entity 的 DAO 接口类全部声明成 abstract 的到这里来。 4. Google 会在编译时自动帮我们生成这些抽象类和方法的实现,代码在 app/build/generated/source/apt/debug

测试调用

以增加一条数据为例:

UserEntity userEntity = new UserEntity("NAME, "AGE");    
AppDatabase.getDatabase(getApplicationContext()).getUserEntityDao().addUser(userEntity);

上面的语句需要放到异步线程去调用,否则 Room 会直接 crash 掉你的 app 告诉你不这样做容易阻塞 UI 线程。虽然粗暴了一些,但想想也是合理的。再回到这段代码,会发现 Room 在实际场景中的用法非常简单,就是在任何你想操作数据库的地方,先拿到 database 对象,然后再拿到 DAO 对象,接着调用 DAO 里面定义的方法即可。而这些方法的具体实现,我们只需要写少量的 sql 语句,剩下的全部根据注解在编译时自动生成了,Simple and easy。

总结

以上就是对 Room 库使用方法的一个简单介绍,如果你看官方文档一头雾水的话,不如先从这个小例子起步,再对照回官方文档去深挖。其实 Room 的用法以及功能远不止这些,通过与 ViewModel 还有 LiveData 结合,可以轻松实现 db 以及对象的 observable,做到在 UI 的声明周期内,只要 db 数据变化,可以主动更新到 UI,不用再写繁琐的 ContentProvider 与 ContentObserver。而接下来有时间我也会继续学习 Android Architecture Components,争取把这个系列文章继续写下去。

 

 

 

 

 

 

 

这篇关于Android Room Library 简单使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/755462

相关文章

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没