【Android】Room数据库的简单使用方法

news/2024/5/20 12:19:17

Room数据库的使用方法

目录

  • 1、添加Room数据库的依赖
  • 2、Entity——定义实体类
    • 2.1 定义主键——PrimaryKey
    • 2.2 字段注解——ColumnInfo
  • 3、Dao——定义数据访问对象
  • 4、Database——数据库
    • 4.1 通过回调观察数据库是否创建成功
  • 5、使用时注意点
  • 6、编写异步 DAO 查询
    • 6.1 写异步单次查询
    • 6.2 编写可观察查询

参考文档:
[1] 使用 Room 实体定义数据
[2] 使用 Android Jetpack 的 Room 部分将数据保存到本地数据库。
[3] 实体类介绍
[4] RoomAPI、依赖
[5] 编写异步Dao查询

1、添加Room数据库的依赖

//Room
implementation "androidx.room:room-runtime:2.6.1"
annotationProcessor "androidx.room:room-compiler:2.6.1"//Rxjava
implementation "androidx.room:room-rxjava3:2.6.1"

Room是由三大部分组成的:

  1. Entity:数据库中表对应的Java实体
  2. DAO:操作数据库的方法
  3. Database:创建数据库

2、Entity——定义实体类

@Entity:

  • 用于定义数据库表结构。
  • 包含以下常用属性:
    • tableName: 指定表名。
    • primaryKeys: 指定主键字段。
    • indices: 定义索引。
    • foreignKeys: 定义外键关系

默认情况下,Room 将类名称用作数据库表名称。如果您希望表具有不同的名称,请设置 @Entity 注解的 tableName 属性。

同样,Room 默认使用字段名称作为数据库中的列名称。

@Entity(tableName = "users")
public class User {@PrimaryKey(autoGenerate = true)public int id;@ColumnInfo(name = "first_name")public String firstName;@ColumnInfo(name = "last_name")public String lastName;
}

2.1 定义主键——PrimaryKey

每个 Room 实体都必须定义一个主键,用于唯一标识相应数据库表中的每一行。

  1. @PrimaryKey:
    • 用于标记主键字段。
    • 包含以下常用属性:
      • autoGenerate: 是否自动生成主键值。
      • 注意:自增主键必须为int型。

2.2 字段注解——ColumnInfo

  1. @ColumnInfo:
    • 用于定义表字段。
    • 包含以下常用属性:
      • name: 指定字段名,也就是表的列名
      • typeAffinity: 指定字段类型。
      • defaultValue:设置默认值,未指定值时的默认值

通过 typeAffinity 属性,可以指定字段的数据类型,如 TEXTINTEGER 等。

📌注意数据需要均为Public


@Entity
public class HistoryData {@PrimaryKey(autoGenerate = true)public int id;@ColumnInfo(typeAffinity = ColumnInfo.TEXT)public LocalDate birthDate;@ColumnInfo(name = "Name")public String name;@ColumnInfo(defaultValue = "18")public int age;}

在这个例子中,birthDate 字段在数据库中会被存储为 TEXT 类型。

3、Dao——定义数据访问对象

常用注解包括:

  1. @Query:
    • 用于定义数据库查询语句。
    • 可以返回 FlowableObservableSingleMaybe 等 RxJava 类型。
  2. @Insert@Update@Delete:
    • 用于定义数据库增、改、删操作。
    • 可以返回 longintvoid 等类型,表示受影响的行数。
@Dao
public interface HistoryDao {/*** 向数据库添加数据** @param data*/@Insertvoid insertData(HistoryData data);/*** 删除数据库所有数据*/@Query("DELETE FROM HistoryData")void deleteDataAll();
}

4、Database——数据库

以下代码定义了用于保存数据库的 HistoryDatabase 类。 HistoryDatabase 定义数据库配置,并作为应用对持久性数据的主要访问点。数据库类必须满足以下条件:

  • 该类必须带有 @Database 注解,该注解包含列出所有与数据库关联的数据实体的 entities 数组。
  • 该类必须是一个抽象类,用于扩展 RoomDatabase。
  • 对于与数据库关联的每个 DAO 类,数据库类必须定义一个具有零参数的抽象方法,并返回 DAO 类的实例。
@Database(entities = HistoryData.class, version = 1)
public abstract class HistoryDatabase extends RoomDatabase {public abstract HistoryDao historyDao();
}

请注意:

📌如果您的应用在单个进程中运行,在实例化 HistoryDatabase 对象时应遵循单例设计模式。每个 RoomDatabase 实例的成本相当高,而您几乎不需要在单个进程中访问多个实例。

用法举例:


@Database(entities = HistoryData.class, version = 1)
public abstract class HistoryDatabase extends RoomDatabase {private static volatile HistoryDatabase historyDB = null;//单例模式双检锁public static HistoryDatabase getInstance(Context context) {if (historyDB == null) {synchronized (HistoryDatabase.class) {if (historyDB == null) {historyDB = Room.databaseBuilder(context.getApplicationContext(), HistoryDatabase.class, "location_History").build();}}}return historyDB;}public abstract HistoryDao historyDao();
}

📌如果您的应用在多个进程中运行,请在数据库构建器调用中包含 enableMultiInstanceInvalidation()。这样,如果您在每个进程中都有一个 AppDatabase 实例,可以在一个进程中使共享数据库文件失效,并且这种失效会自动传播到其他进程中 AppDatabase 的实例。

用法举例:

@Database(entities = HistoryData.class, version = 1)
public abstract class HistoryDatabase extends RoomDatabase {public static HistoryDatabase getDatabase(Context context) {return Room.databaseBuilder(context.getApplicationContext(),HistoryDatabase.class, "chat_database").enableMultiInstanceInvalidation().build();}public abstract HistoryDao historyDao();
}

4.1 通过回调观察数据库是否创建成功

通过RoomDatabase提供的Callback()回调方法观测数据库状态。

Callback提供了三个回调方法:分别是数据库第一次被创建时调用,数据库打开时调用,数据库被销毁迁移后调用

我们在创建数据库时添加上这个回调方法的实现类即可:

@Database(entities = HistoryData.class, version = 1,exportSchema = false)
public abstract class HistoryDatabase extends RoomDatabase {public abstract HistoryDao historyDao();private static volatile HistoryDatabase historyDB = null;public static HistoryDatabase getInstance(Context context) {if (historyDB == null) {synchronized (HistoryDatabase.class) {if (historyDB == null) {historyDB = Room.databaseBuilder(context, HistoryDatabase.class, "locationHistory").addCallback(roomCallback).build();}}}return historyDB;}// 回调函数,可在数据库创建、打开和关闭时执行操作private static RoomDatabase.Callback roomCallback = new RoomDatabase.Callback() {@Overridepublic void onCreate(@NonNull SupportSQLiteDatabase db) {super.onCreate(db);Log.d("HistoryDatabase", "Database created successfully");}};
}

5、使用时注意点

为防止查询阻止界面,Room 不允许在主线程上访问数据库。 此限制意味着您必须将DAO 查询设为异步。Room 库包含与多个不同框架的集成,以提供异步查询执行功能。


// 创建一个ExecutorService
ExecutorService executor = Executors.newSingleThreadExecutor();// 提交删除操作到ExecutorService中执行
executor.submit(() -> {HistoryData data = new HistoryData();data.setLocationName("天津");HistoryDatabase.getInstance(getContext()).historyDao().insertData(data);//在主线程中更改UIrunOnUiThread(() -> {});});// 关闭ExecutorService
executor.shutdown();

6、编写异步 DAO 查询

Java 与 RxJava

如果您的应用使用 Java 编程语言,则您可以使用 RxJava 框架的专用返回类型编写异步 DAO 方法。Room 支持以下 RxJava 2 返回值类型:

  • 对于单次查询,Room 2.1 及更高版本支持 Completable、Single<T> 和 Maybe<T> 返回值类型。
  • 对于可观察查询,Room 支持 Publisher<T>、Flowable<T> 和 Observable<T> 返回值类型。

此外,Room 2.3 及更高版本支持 RxJava 3。

📌注意:如需将 RxJava 与 Room 搭配使用,您必须在 build.gradle 文件中添加 room-rxjava2 工件或 room-rxjava3 工件。如需了解详情,请参阅声明依赖项。

6.1 写异步单次查询

单次查询是指仅执行一次并在执行时获取数据快照的数据库操作。以下是异步单次查询的一些示例:

@Dao
public interface UserDao {@Insert(onConflict = OnConflictStrategy.REPLACE)public Completable insertUsers(List<User> users);@Updatepublic Completable updateUsers(List<User> users);@Deletepublic Completable deleteUsers(List<User> users);@Query("SELECT * FROM user WHERE id = :id")public Single<User> loadUserById(int id);@Query("SELECT * from user WHERE region IN (:regions)")public Single<List<User>> loadUsersByRegion(List<String> regions);
}

6.2 编写可观察查询

可观察查询是指在查询引用的任何表发生更改时发出新值的读取操作。

您可能需要用到可观察查询的一种情形是,帮助您在向底层数据库中插入项或者更新或移除其中的项时及时更新显示的列表项。下面是可观察查询的一些示例:

@Dao
public interface UserDao {@Query("SELECT * FROM user WHERE id = :id")public Flowable<User> loadUserById(int id);@Query("SELECT * from user WHERE region IN (:regions)")public Flowable<List<User>> loadUsersByRegion(List<String> regions);
}

http://www.mrgr.cn/p/38484748

相关文章

python作业五

题目&#xff1a;注册登录 制作一个注册登录模块 注册&#xff1a;将用户填入的账户和密码保存到一个文件(users.bin) 登陆&#xff1a;将用户填入账户密码和users.bin中保存的账户密码进行比对,如果账户和密码完全相同 那 么登录成功&#xff0c;否则登录失败…

Linux基础之git与调试工具gdb

目录 一、git的简单介绍和使用方法 1.1 git的介绍 1.2 git的使用方法 1.2.1 三板斧之git add 1.2.2 三板斧之git commit 1.2.3 三板斧之git push 二、gdb的介绍和一些基本使用方法 2.1 背景介绍 2.2 基本的使用方法 一、git的简单介绍和使用方法 1.1 git的介绍 Git是一…

国科大深度学习期末历年试卷

本文借鉴 国科大深度学习复习 深度学习期末 深度学习2020 一&#xff0e;名词解释&#xff08;每个2分&#xff0c;共10分&#xff09; 深度学习&#xff0c;稀疏自编码器&#xff0c;正则化&#xff0c;集成学习&#xff0c;Dropout 二&#xff0e;简答题&#xff08;每题…

ICode国际青少年编程竞赛- Python-2级训练场-列表入门

ICode国际青少年编程竞赛- Python-2级训练场-列表入门 1、 Dev.step(3)2、 Flyer.step(1) Dev.step(-2)3、 Flyer.step(1) Spaceship.step(7)4、 Flyer.step(5) Dev.turnRight() Dev.step(5) Dev.turnLeft() Dev.step(3) Dev.turnLeft() Dev.step(7) Dev.turnLeft() Dev.…

一文搞懂 ARM 64 系列: ADC

一文搞懂 ARM 64 系列: ADC1 指令语法 adc <Xd>, <Xn>, <Xm>2 指令语义 adc就是带「进位」加法,指令中的c就是英文carry。 整个指令等价于: (Xd, _) = Xn + Xm + PSTATE.C也就是将寄存器Xn,寄存器Xm,PSTATE中的「进位」标志相加,将相加的结果写入寄存器X…

初探 Google 云原生的CICD - CloudBuild

大纲 Google Cloud Build 简介 Google Cloud Build&#xff08;谷歌云构建&#xff09;是谷歌云平台&#xff08;Google Cloud Platform&#xff0c;GCP&#xff09;提供的一项服务&#xff0c;可帮助开发人员以一致和自动化的方式构建、测试和部署应用程序或构件。它为构建和…

幂等设计的8种实现方式

即无论操作执行一次还是多次&#xff0c;其效果始终如一&#xff0c;不会有差异。这就是幂等性。 什么是幂等性&#xff1f; 接口幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的&#xff0c;不会因为多次点击而产生了副作用。比如&#xff1a;公交车刷卡…

Linux Shell 脚本专题

本文介绍了Linux Shell环境变量和脚本使用的常用知识点。V1.0 2024年5月8日 发布于博客园目录常用环境变量一、环境变量的概念1、环境变量的含义2、环境变量的分类3、Linux环境变量二、常用的环境变量1、查看环境变量2、常用的环境变量三、设置环境量1、系统环境变量2、用户环境…

Web实操(6),基础知识学习(24~)

1.[ZJCTF 2019]NiZhuanSiWei1 &#xff08;1&#xff09;进入环境后看到一篇php代码&#xff0c;开始我简单的以为是一题常规的php伪协议&#xff0c;多次试错后发现它并没有那么简单&#xff0c;它包含了基础的文件包含&#xff0c;伪协议还有反序列化 &#xff08;2&#x…

使用docker-compose编排lnmp(dockerfile)完成wordpress

文章目录 使用docker-compose编排lnmp&#xff08;dockerfile&#xff09;完成wordpress1、服务器环境2、Docker、Docker-Compose环境安装2.1 安装Docker环境2.2 安装Docker-Compose 3、nginx3.1 新建目录&#xff0c;上传安装包3.2 编辑Dockerfile脚本3.3 准备nginx.conf配置文…

ue引擎游戏开发笔记(35)——为射击添加轨道,并显示落点

1.需求分析&#xff1a; 我们只添加了开枪特效&#xff0c;事实上并没有实际的效果产生例如弹痕&#xff0c;落点等等。所以逐步实现射击的完整化&#xff0c;先从实现落点开始。 2.操作实现&#xff1a; 1.思路&#xff1a;可以这样理解&#xff0c;每次射击的过程是一次由摄…

视频提取gif怎么制作?试试这个网站一键转换

通过把视频转换成gif动图的操作能够更加方便的在各种平台上分享和传播。相较于视频&#xff0c;gif图片具有较小的文件体积&#xff0c;gif动图能够快速的加载播放&#xff0c;不需要等待就能快速欣赏。很适合从事新媒体之类的小伙伴&#xff0c;可以用来做展示、宣传等。想要实…

公考学习|基于SprinBoot+vue的公考学习平台(源码+数据库+文档)

公考学习平台目录 目录 基于SprinBootvue的公考学习平台 一、前言 二、系统设计 三、系统功能设计 5.1用户信息管理 5.2 视频信息管理 5.3公告信息管理 5.4论坛信息管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&…

SOL链DApp智能合约代币质押挖矿分红系统开发

随着区块链技术的不断发展和普及&#xff0c;越来越多的项目开始探索基于区块链的去中心化应用&#xff08;DApp&#xff09;。Solana&#xff08;SOL&#xff09;作为一条高性能、低成本的区块链网络&#xff0c;吸引了众多开发者和项目&#xff0c;其中包括了各种类型的DApp&…

YOLOv5改进(二)BiFPN替换Neck网络

前言 针对红绿灯轻量化检测&#xff0c;上一节使用MobileNetv3替换了主干网络&#xff0c;本篇将在使用BiFPN替换Neck的方式优化算法~ 往期回顾 YOLOv5改进&#xff08;一&#xff09;MobileNetv3替换主干网络 目录 一、BiFPN简介二、改进方法一第一步&#xff1a;在common.…

链表的阶乘

int FactorialSum(List L) {int res 0; // 结果初始化struct Node* x L; // 从链表的头节点开始// 遍历链表中的每一个节点while (x ! NULL) {int data x->Data; // 当前节点的值int y 1; // 用于计算当前节点值的阶乘// 计算当前节点值的阶乘for (int j 1; j < dat…

SCI一区 | MFO-CNN-LSTM-Mutilhead-Attention多变量时间序列预测(Matlab)

SCI一区 | MFO-CNN-LSTM-Mutilhead-Attention多变量时间序列预测&#xff08;Matlab&#xff09; 目录 SCI一区 | MFO-CNN-LSTM-Mutilhead-Attention多变量时间序列预测&#xff08;Matlab&#xff09;预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现MFO-CNN…

OpenDiary 24.5

我去!五月了我去!五月了 一亿年没更日寄了pixiv 100277433四月后日谈 鉴于整个四月基本没记日记,有必要开展一次考古活动 因为考古是比较困难的事情,所以想到什么就写什么了打了一整月的 p5r,四月下旬全都在高强度 p5r,每天都情不自禁打很长很长时间 一个月打了 93h 之多…

Comate,一款基于文心大模型的智能编程助手

一、官网 Baidu Comate官网 二、安装VSCode 如何下载安装VSCode 三、VSCode安装Comate 安装方式1 访问Comate官网点击 立即安装Comate插件 按钮快速安装 安装方式2 访问VSCode市场中的BaiduComate 点击 Install 按钮访问扩展详情界面 2.打开VSCode 3.安装Comate 四、…

Linux进程——Linux进程间切换与命令行参数

前言&#xff1a;在上一篇了解完进程状态后&#xff0c;我们简单了解了进程优先级&#xff0c;然后遗留了一点内容&#xff0c;本篇我们就来研究进程间的切换&#xff0c;来理解上篇提到的并发。如果对进程优先级还有没理解的地方可以先阅读&#xff1a; Linux进程优先级 本篇…