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

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.mzph.cn/pingmian/8443.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CSS】认识CSS选择器及各选择器对应的用法

目录 一、什么是CSS&#xff1f; 二、CSS 选择器 1. 标签选择器 2. 类选择器 3. ID选择器 4. 通配符选择器 5. 复合选择器 一、什么是CSS&#xff1f; CSS(Cascading Style Sheet)&#xff0c;层叠样式表。它与 HTML&#xff08;超文本标记语言&#xff09;一起使用&am…

Django-新冠疫情数据分析系统-67684

目 录 摘要 1 绪论 1.1 研究背景 1.2论文结构与章节安排 2 新冠疫情数据分析系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析…

2024.5.8 2.二叉树的最大深度 (简单)

给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3 示例 2&#xff1a; 输入&#xff1a;root [1,null,2] 输…

批量图片重命名及汇总

又一堆图片文件需要处理... 源文件分布&#xff1a; 有N个文件夹&#xff0c;每个文件夹下又有M个子文件夹&#xff0c;每个子文件夹下有X张图片。 例如文件夹A下有子文件夹A1,A2,A3&#xff0c;子文件夹A1下有图片a-1,a-2,a-3...... 处理目标&#xff1a; 1、将所有图片汇…

五月最新流行音乐网,整点干货(10个网站)听歌就要自由!

随着互联网的迅猛发展&#xff0c;音乐产业也迎来了前所未有的变革。如今&#xff0c;我们无需再依赖传统的唱片店或电台&#xff0c;就能轻松接触到来自世界各地的音乐。而“最新流行音乐网”正是这一变革的产物&#xff0c;为广大音乐爱好者提供了一个探索音乐潮流的新天地。…

将大概的流程具体还是看源码

之前看源码的时候呢没有文字整理&#xff0c;想来还是写一个大概的流程吧&#xff0c;具体是无法用文字描述 spring源码真的yyds&#xff0c;数据结构 反射 父子类 接口…玩得溜到飞起 博大精深呐 后期不断喜欢ing&#xff01; springApplication.run方法 获取了一个Configu…

无刷电机和有刷电机的区别

无刷电机和有刷电机的区别 无刷电机的定子上绕着线圈&#xff0c;线圈通常是成对出现的&#xff0c;通过控制电路为每一对线圈按照一定顺序输入电流&#xff0c;就可以产生旋转的磁场 它还有一个永磁体转子&#xff0c;现在多采用高磁能级的稀土铷铁硼材料&#xff0c;体积更小…

DBdoctor产品介绍

基本信息 DBdoctor是聚好看科技股份有限公司自主研发的一款数据库内核级性能诊断工具&#xff0c;首次将eBPF技术聚焦在了数据库领域&#xff0c;一分钟内定位数据库性能问题并给出优化建议&#xff0c;实现数据库性能诊断百倍提效。 免费下载 请在PC端打开以下链接&#x…

ps5电玩计时收费系统软件教程,电玩店适合的计时器,电脑定时语音提醒

ps5电玩计时收费系统软件教程&#xff0c;电玩店适合的计时器&#xff0c;电脑定时语音提醒 一、前言 以下软件操作教程以&#xff0c;佳易王电玩计时计费管理软件为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 1、计时计费功能&#xff1a;只…

【日志革新】在ThinkPHP5中实现高效TraceId集成,打造可靠的日志追踪系统

问题背景 最近接手了一个骨灰级的项目&#xff0c;然而在项目中遇到了一个普遍的挑战&#xff1a;由于公司采用 ELK&#xff08;Elasticsearch、Logstash、Kibana&#xff09;作为日志收集和分析工具&#xff0c;追踪生产问题成为了一大难题。尽管 ELK 提供了强大的日志分析功…

Spring:OAuth2.0

文章目录 一、认证与授权二、OAuth2.0介绍 一、认证与授权 认证&#xff08;Authentication&#xff09;与授权&#xff08;Authorization&#xff09;在网络安全和系统管理中是两个重要的概念&#xff0c;它们各自有不同的作用和目标。 认证是验证确认身份以授予对系统的访问…

RAG解决方案:解决LLM大模型私域数据缺失问题

目前LLM大模型是一种预训练模型(训练完成后 信息就会截止)&#xff0c;那么在获取最新数据和私域数据时候&#xff0c;LLM会有无法给出相关回答的问题。 那么RAG方案可以一定程度上解决这个问题。 用户搜索后&#xff0c;会先在检索系统中检索&#xff0c;然后再把问题和私域数…

夏天一到,手机越用越烫?怎样降低持久使用手机时的温度?

夏季来临&#xff0c;手机的温度也随着使用环境的温度升高变得更容易发热。 虽说属于正常的物理现象&#xff0c;但手机过热用起来还是不太舒服&#xff0c;还容易出现过热提醒&#xff0c;导致除“拨号”和“联系人”外&#xff0c;无法使用其它应用。 分享几个减少功耗的小技…

JAVA版本的ATM编程问题记录

前段时间用C语言写了个银行ATM系统&#xff0c;还写了一篇文章记录了一些&#xff0c;C语言的ATM文章。后来又用IDEA写了一个JAVA版本的银行ATM。有人就会问为啥浪费这个时间写ATM呢&#xff1f;&#x1f9d0;其实是我本科代码没学好&#xff0c;所以现在想利用比较熟悉的ATM系…

Spring Web MVC 快速入门

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;Spring学习之路&#x1f4d5;格言&#xff1a;吾愚多不敏&#xff0c;而愿加学欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 什么是Spring MVC&#xff1f; MVC模式介绍 ​编辑学习Spring MVC…

node.js对数据库mysql的连接与操作(增、删、改、查、五种SQL语法)

前提&#xff1a;先在vscode终端下载安装mysql&#xff1a;npm install mysql -save 步骤总结&#xff1a; (1)建立与数据库的连接 (2)做出请求&#xff1a; 实际上就是操作mysql里的数据。增删改查 insert、delete、updata、select (3)通过回调函数获取结果 一、什么是SQ…

【Kubernetes集群一主二从安装教程】

文章目录 环境准备主机间做信任安装ansible工具 升级内核版本使用elrepo源升级内核查看最新版内核安装最新的内核版本设置系统默认内核设置默认内核为我们刚才升级的内核版本 初始化关闭防火墙关闭selinux关闭swap修改主机名修改hosts文件将桥接的IPv4流量传递到iptables的链配…

nlp课设 - 基于BERT 的情感分类

基于BERT 的情感分类 主要论文&#xff1a; BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding&#xff08;双向Transformer 的预训练&#xff09; 核心技术&#xff1a; Embedding 、Attention --> Transformer 任务简介、拟解决问题…

09 - 数据清洗案例

流程图 kettle 面板图片 操作步骤 1、订阅数据源&#xff08;kafka consumer&#xff09; 2、抽取字段并转换key&#xff08;JSON input&#xff09; 3、判断img字段是否有值&#xff0c;有的话进行url转base64&#xff08;JavaScript 代码&#xff09; // 获取输入字段的值 v…

流量分析利器arkime的学习之路(三)---结合Suricata攻击检测

1、基础 Arkime安装部分参考《流量分析利器arkime的学习之路&#xff08;一&#xff09;—安装部署》 在此基础上安装suricata软件并配置。 2、安装suricata yum install suricate 可能依赖的文件包括libyaml&#xff0c;PyYAML&#xff0c;这些可能在之前安装arkime或者其他…