【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
     */
    @Insert
    void 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() {
        @Override
        public 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);
    
    //在主线程中更改UI
    runOnUiThread(() -> {
        
    });

});

// 关闭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);

    @Update
    public Completable updateUsers(List<User> users);

    @Delete
    public 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.mfbz.cn/a/604378.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

24_Scala集合Map

文章目录 Scala集合Map1.构建Map2.增删改查3.Map的get操作细节 Scala集合Map –默认immutable –概念和Java一致 1.构建Map –创建kv键值对 && kv键值对的表达 –创建immutable map –创建mutable map //1.1 构建一个kv键值对 val kv "a" -> 1 print…

Java IO流(二)

1. 缓冲流 1.1 字节缓冲流概述 当对文件或其他数据源进行频繁的读/写操作时&#xff0c;效率比较低&#xff0c;这时如果使用缓存流就能够更高效地读/写信息。 比如&#xff0c;可以使用缓冲输出流来一次性批量写出若干数据减少写出次数来提高写出效率。 如果用生活中的例子做…

多模态EDA论文小记

论文地址 该论文主要改进点是&#xff1a;通过动态化局部搜索中每个集群大小&#xff0c;高斯和柯西分布共同产生个体。总的来说改进点不多&#xff0c;当然也可能是笔者还没发现。 局部搜索 划分集群 划分集群有两个策略分别是&#xff1a; 随机生成一个点作为中心点&…

什么软件可以把视频合并在一起?6个软件教你快速进行视频编辑

什么软件可以把视频合并在一起&#xff1f;6个软件教你快速进行视频编辑 当你需要对视频进行编辑和合并时&#xff0c;选择合适的软件可以极大地提高工作效率和编辑质量。以下是六款被广泛认可且功能强大的视频编辑软件&#xff0c;它们可以帮助你快速、高效地进行视频编辑和合…

PDF转word转ppt软件

下载地址&#xff1a;PDF转word转ppt软件.zip 平时工作生活经常要用到PDF转word转ppt软件&#xff0c;电脑自带的又要开会员啥的很麻烦&#xff0c;现在分享这款软件直接激活就可以免费使用了&#xff0c;超级好用&#xff0c;喜欢的可以下载

C++从入门到精通---模版

文章目录 泛型编程函数模版模版参数的匹配原则类模版类模版的定义格式类模版的实例化 总结 泛型编程 泛型编程是一种编程范式&#xff0c;旨在实现通用性和灵活性。它允许在编写代码时使用参数化类型&#xff0c;而不是具体的类型&#xff0c;从而使代码更加灵活和可重用。 在…

NodeMCU ESP8266 操作 SSD1306 OLED显示屏详解(图文并茂)

文章目录 1 模块介绍2 接线介绍3 安装SSD1306驱动库4 源码分析4.1 硬件兼容性4.2 可能存在的问题总结1 模块介绍 我们将在本教程中使用的OLED显示屏是SSD1306型号:单色0.96英寸显示屏,像素为12864,如下图所示。 OLED显示屏不需要背光,这在黑暗环境中会产生非常好的对比度。…

全面的Partisia Blockchain 生态 4 月市场进展解读

Partisia Blockchain 是一个以高迸发、隐私、高度可互操作性、可拓展为特性的 Layer1 网络。通过将 MPC 技术方案引入到区块链系统中&#xff0c;以零知识证明&#xff08;ZK&#xff09;技术和多方计算&#xff08;MPC&#xff09;为基础&#xff0c;共同保障在不影响网络完整…

Springboot+Vue项目-基于Java+MySQL的个人云盘管理系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

去除图片水印软件-inpaint

一、普通使用教程 亲眼看看使用 Inpaint 从照片中删除不需要的元素是多么容易&#xff1a; 1.1加载图片 1.2 选择要纠正的问题区域 1.3 告别不需要的对象并保存 二、功能 1 修复旧照片 老并不总是意味着坏。我们拥有的一些旧照片对我们来说仍然很重要&#xff0c;因为它们仍…

FPGA ov5640视频以太网传输

1 实验任务 使用DFZU4EV MPSoC 开发板及双目OV5640摄像头其中一个摄像头实现图像采集&#xff0c;并通过开发板上的以太网接口发送给上位机实时显示。 2 Verilog代码 2.1 顶层模块 timescale 1ns / 1ps //以太网传输视频顶层模块module ov5640_udp_pc (input sys_cl…

威客网上招标系统(五)

目录 5 详细设计 5.1 系统首页 5.1.1系统首页&#xff08;网站首页index.jsp&#xff09; 5.1.2 下沙派威客网首页界面说明 5.2 站内新闻信息 5.2.1站内新闻操作界面 5.2.2系统主操作界面说明 5.3威客在线操作界面 5.3.1 威客在线操作界面 5.3.2威客在线说明 5.4系统…

PCIe下一代线缆标准CopprLink发布

作为业界广泛采用的高速串行点对点互联标准&#xff0c;PCIe自诞生以来历经多次迭代升级&#xff0c;现已成为CPU、GPU、FPGA、SSD等计算设备间不可或缺的互连桥梁。PCIe 7.0标准更是将数据传输速率提升至令人惊叹的32 GB/s&#xff08;每通道&#xff09;。 然而&#xff0c;面…

[MySQL数据库] Java的JDBC编程(MySQL数据库基础操作完结)

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (91平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;Java …

力扣hot100:199. 二叉树的右视图/437. 路径总和 III(dfs/回溯/树上前缀和/哈希表)

文章目录 一、LeetCode&#xff1a;199. 二叉树的右视图二、LeetCode&#xff1a;437. 路径总和 III 一、LeetCode&#xff1a;199. 二叉树的右视图 LeetCode&#xff1a;199. 二叉树的右视图 差点因为是个中等题打退堂鼓。其实比较简单。 右视图实际上只需要找到&#xff0c…

VitePress快速上手

完整教程&#xff1a;https://blog.share888.top/note/front-end/vitePress/01-vitePress%E5%AE%89%E8%A3%85.html https://blog.share888.top/ VitePress快速上手 官方文档&#xff1a;https://vitepress.dev/zh/guide/markdown VitePress中文网&#xff1a;https://vitejs…

二叉树的基础遍历2.0

1.0入口&#xff1a;二叉树的基础遍历-CSDN博客 在1.0中使用的是简单的结构体建树&#xff0c;本文注重用二维vector建树。 前序&#xff0c;中序和后序的分析1.0已给出&#xff0c;本文不做过多介绍&#xff0c;本文重点讲二叉树的层序遍历。 先奉上前中后序的代码&#xf…

基士得耶(GESTETNER ) CP 6303C 速印机简介

规格参数 产品名称: 基士得耶&#xff08;GESTETNER &#xff09; CP 6303C 速印机 品牌中文: 基士得耶/GESTETNER 型 号: CP-6303C 工作方式&#xff1a; 数码式 制版方式: 自动印刷 制版时间&#xff1a; 曝光玻璃: 31秒(A4长边…

解决windows中的WS Llinux子系统(unbantu2204)访问网络失败问题?

一、问题描述 unbantu先前可以正常访问网络&#xff0c;后面用着用着发现上不了网了&#xff0c; 出现如下异常 Hmm. We’re having trouble finding that site.We can’t connect to the server at www.iqiyi.com.If you entered the right address, you can:Try again late…

xhs 旋转滑块流程分析

声明 本文章中所有内容仅供学习交流&#xff0c;抓包内容、敏感网址、数据接口均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&#xff0c;请联系我立即删除&#xff01; 前言 本文首发于公众号…