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

news2025/1/12 23:27:42

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.coloradmin.cn/o/1654241.html

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

相关文章

LabVIEW波浪发电平台浮筒取能效率数据采集系统

LabVIEW波浪发电平台浮筒取能效率数据采集系统 随着化石能源的逐渐减少以及能源价格的上升&#xff0c;寻找可替代的、可再生的、清洁的能源成为了世界各国的共识。波浪能作为一种重要的海洋能源&#xff0c;因其巨大的潜力和清洁性&#xff0c;近年来受到了广泛关注。开发了一…

数据结构学习——二叉树

1. 树概念及结构 1.1 树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。 有一个特殊的结点&…

基于Springboot的校园健康驿站管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的校园健康驿站管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系…

C语言:指针(1)

1. 内存和地址 内存划分为⼀个个的内存单元&#xff0c;每个内存单元的⼤⼩取1个字节。 计算机中常⻅的单位&#xff08;补充&#xff09;&#xff1a; ⼀个⽐特位可以存储⼀个2进制的位1或者0 C语⾔中给地址起了新的名字叫&#xff1a;指针。 内存单元的编号地址指针。 1.…

重写muduo之Thread、EventLoopThread、EventLoopThreadPool

目录 1、概述 2、Thread 2.1 Thread.h 3、EventLoopThread 3.1 EventLoopThread.h 3.2 EventLoopThread.cc 4、 EventLoopThreadPool 4.1 EventLoopThreadPool.h 4.2 EventLoopThreadPool.cc 1、概述 管理事件循环线程的调度的 打包了一个EventLoop和线程&#xff0c;…

每日OJ题_记忆化搜索①_力扣509. 斐波那契数(四种解法)

目录 记忆化搜索概念和使用场景 力扣509. 斐波那契数 解析代码1_循环 解析代码2_暴搜递归 解析代码3_记忆化搜索 解析代码4_动态规划 记忆化搜索概念和使用场景 记忆化搜索是一种典型的空间换时间的思想&#xff0c;可以看成带备忘录的爆搜递归。 搜索的低效在于没有能够…

Mysql基础(五)外键约束

一 外键 激励&#xff1a; 每天进步一点点即可 ① 思考 1、在MySQL中,我们知道主键 PRIMARY KEY的主要作用是唯一区分表中的各个行 [记录];思考&#xff1a;但是对于外键 foreign key比较陌生? 那么外键作用以及限制条件和目的呢? ② 外键的定义 1、外键是某个表 A中…

DRF视图基类使用方法

【 一 】drf之请求 请求对象Request 【 0 】前言 ​ 在 Python 中&#xff0c;通常通过 request 对象来处理 HTTP 请求&#xff0c;尤其是在 web 开发中&#xff0c;比如使用 Django、Flask 等框架时会经常接触到这个对象。request 对象是框架提供的&#xff0c;用于封装客户…

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

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

实战28套JAVA高端架构P6/P7/P8架构—全栈架构

概述 Java SE Java SE&#xff08;Java Platform&#xff0c;Standard Edition&#xff09;。Java SE 以前称为J2SE。它允许开发和部署在桌面、服务器、嵌入式环境和实时环境中使用的Java应用程序。Java SE 包含了支持Java Web 服务开发的类&#xff0c;并为Java Platform&…

《从零开始,搭建一个简单的UVM验证平台》实操

最近的工作中需要用UVM平台去仿真软件同事写的C程序&#xff0c;虽然只要用EDA同事已经搭好的UVM平台稍微改改就行&#xff0c;但对于我这种从未接触过UVM甚至都没用过System Verilog的纯FPGA工程师来说还是很有难度的&#xff0c;因为我对这方面一点概念都没有。 基于此&…

批量网络装机

1. PXE概念 PXE(preboot execute environment&#xff0c;预启动执行环境)是由Intel公司开发的最新技术&#xff0c;工作于Client/Server的网络模式&#xff0c;支持工作站通过网络从远端服务器下载映像&#xff0c;并由此支持通过网络启动操作系统。在启动过程中&#xff0c;…

【智能算法】雪消融优化算法(SAO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2023年&#xff0c;L Deng受到雪升华和融化行为启发&#xff0c;提出了雪消融优化算法&#xff08;Snow Ablation Optimizer, SAO&#xff09;。 2.算法原理 2.1算法思想 SAO模拟了雪的…

微信云小程序快速上手云数据库+云函数+云存储的操作

&#x1f680; 作者 &#xff1a;“二当家-小D” &#x1f680; 博主简介&#xff1a;⭐前荔枝FM架构师、阿里资深工程师||曾任职于阿里巴巴担任多个项目负责人&#xff0c;8年开发架构经验&#xff0c;精通java,擅长分布式高并发架构,自动化压力测试&#xff0c;微服务容器化k…

JSP技术讲解

目录 1、JSP简介 2、JSP体验 3、JSP运行原理 4、JSP基本语法 5、JSP指令 6、JSP内置九大对象 7、JSP标签 8、JSP配置 9、JSP排错 10、总结 在前面的Servlet学习中发现Servlet本质是一个java程序&#xff0c;因此Servlet更加擅长编写程序的业务逻辑&#xff0c;而如果要…

Java特性之设计模式【代理模式】

一、代理模式 概述 在代理模式&#xff08;Proxy Pattern&#xff09;中&#xff0c;一个类代表另一个类的功能。这种类型的设计模式属于结构型模式 在代理模式中&#xff0c;我们创建具有现有对象的对象&#xff0c;以便向外界提供功能接口 主要解决&#xff1a; 在直接访问…

Apple强大功能:在新款 iPad Pro 和 iPad Air 中释放 M4 芯片潜力

Apple 的最新强大功能&#xff1a;在新款 iPad Pro 和 iPad Air 中释放 M4 芯片的潜力 概述 Apple 推出配备强大 M4 芯片的最新 iPad Pro 和 iPad Air 型号&#xff0c;再次突破创新界限。新一代 iPad 有望彻底改变我们的工作、创造和娱乐方式。凭借无与伦比的处理能力、令人惊…

CTF-reverse,逆向分析,对“左移4或右移4,即(x<<4) | (x >>4)的加密探讨

博主在刷题过程中遇上这样一个有意思的加密&#xff08;如下图&#xff09;&#xff0c;苦苦思索其逆向运算&#xff0c;被硬控了很久&#xff0c;也没搜到什么资料来解释这个问题&#xff08;也许是太简单&#xff1f;&#xff1f;蒟蒻博主怀疑人生……&#xff09; 经过博主不…

【MATLAB源码-第205期】基于matlab的LDPC译码算法仿真,对比BF算法,最小和算法,对数BP和概率BP四种算法。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 LDPC 码简介 LDPC码是一种通过稀疏奇偶校验矩阵定义的线性分组码&#xff0c;1962年由Gallager首次提出。这种码具有高效的解码性能&#xff0c;尤其在接近香农极限的情况下&#xff0c;其性能表现尤为突出。LDPC码的核心特…

Logstash分析MySQL慢查询日志实践

删除匹配到的行&#xff0c;当前行信息不记录到message中