Android Room DataBase

news2024/9/21 14:49:32

Room数据库是在Sqlite的基础上,进行了封装和优化。这让我们可以摆脱,繁琐的数据库操作

在module的gradle里面,加入:

dependencies {

    annotationProcessor "androidx.room:room-compiler:2.3.0"
    implementation 'androidx.room:room-common:2.3.0'
    implementation 'androidx.room:room-runtime:2.3.0'
    implementation 'androidx.room:room-runtime:2.3.0'
 
}

一、Room的三大组件

Room的三大组件,换言之,即是Room由哪三个东西组成。

    Entity:每一个Entity是一个类,同时也是一张表。默认情况下,类名即是表名,字段名,即是字段名。可以通过注解的形式,进行自定义表名和字段名,这个在下一篇会详细讲解。
    Dao:每一个Dao,定义了一组对Entity的操作(Method, 即方法)。比如,增删查改。

    DataBase:DataBase类似于Manager,通过DataBase,可以获取到任意有绑定到DataBase的Dao对象,再通过Dao对象,就可以对每一个Entity进行操作。作为一个DataBase类,必须满足以下三个条件:

    1、DataBase类必须是继承自RoomDataBase,并且其本身,必须是抽象类。
    2、通过在头部以注解的方式(后面会讨论如何做),添加一组Entity。这句话的意思是,只要Entity添加在DataBase类的头部,那该DataBase就可以,对已添加的Entity进行操作。
    3、至少包含一个不带参数的抽象方法,该方法返回一个已绑定的Entity所对应的Dao类型。

二、如何定义Entity

每一个Entity类,都会在其类名定义的前一行,增加一个注解@Entity,来标识该类是Room的一个Entity。每一个字段都有一个注解,这里就列举几个比较简单常见的:

1、@PrimaryKey,表示该字段是主键、@NonNull 表示该字段不允许为空。
2、@ColumnInfo(name = “last_name”),表示该字段是表中的一个字段,字段名为自定义的last_name。
3、@Ignore,表示不对字段进行存储。
4、@Entity(tableName ="meals"),实际数据库表名为meals
其他:

5、主键ID的自增(autoGenerate)。只要设置PrimaryKey的autoGenerate属性为true即可

@PrimaryKey(autoGenerate = true)
 private int id;

6、联合主键(primaryKeys)。与单主键不同的是,联合主键的定义,是作为@Entity的属性的形式,被定义的。并且,关键字是primaryKeys,不是primaryKey,多了一个s。代码如下:

@Entity(primaryKeys = {"firstName", "lastName"})
class User {

    public String firstName;
    public String lastName;

    @Ignore
    Bitmap picture;
}

7、创建索引与唯一性约束。

我们可以通过创建索引,来提高查询的效率,其原理是索引原理。同时,可以创建字段的唯一性约束,来避免创建相同的数据。因为在一张表中,除了主键(id)字段的每条数据都是不同之外,有可能还存在其它字段的数据也不允许重复,比如身份证号码,这时就需要添加唯一性约束。

a)、索引(indices)

创建索引的根本目的,是提高查询的效率。那么,如何在Entity中,创建索引呢?

@Entity(indices = {@Index("name"),
        @Index(value = {"last_name", "address"})})
class User {
    @PrimaryKey
    public int id;

    public String firstName;
    public String address;

    @ColumnInfo(name = "last_name")
    public String lastName;

    @Ignore
    Bitmap picture;
}

b)、唯一性约束(unique)

有时候,我们可能想要某一字段,或多个字段的组合的数据,在表中是唯一的,不重复的。那么,我们可以使用唯一性约束。代码如下:

@Entity(indices = {@Index(value = {"first_name", "last_name"},
        unique = true)})
class User {
    @PrimaryKey
    public int id;

    @ColumnInfo(name = "first_name")
    public String firstName;

    @ColumnInfo(name = "last_name")
    public String lastName;

    @Ignore
    Bitmap picture;
}

三、如何定义Dao

@Dao
public interface dishmealDao {

    @Query("SELECT * FROM meals")
    List<dishmeal> getAllMeals();

    // 获取表中记录的数量
    @Query("SELECT COUNT(*) FROM meals")
    int getMealsCount();

    @Query("SELECT * FROM meals")
    Cursor getMealCursor();

    @Query("SELECT * FROM meals WHERE MealID=:MealID")
    dishmeal getMeal(String MealID);

    @Query("select * from meals where MealID in (:mealids)")
    List<dishmeal> loadMealsByIds(String[] mealids);

    @Query("select * from meals where MealName like :first or MealSpell like :last ")//limit 1
    List<dishmeal> findMealsByName(String first, String last);

    @Query("SELECT * FROM meals WHERE MealName=:MealName")
    List<dishmeal> getMealsByName(String MealName);

    @Query("DELETE FROM meals")
    int deleteAllMeals();

    @Query("DELETE FROM meals WHERE MealID=:MealID")
    int delete(String MealID);

    @Insert
    long insert(dishmeal meal);

    @Update
    int update(dishmeal... meals);

    //动态根据查询条件,查询
    @RawQuery
    List<dishmeal> getMyEntities(SupportSQLiteQuery query);


}

每一个Dao类,都会在其类名定义的前一行,增加一个注解@Dao,来标识该类是Room的一个Dao。每一个方法,都有一个注解,用来表示,这个方法能对表进行的操作。这里,同样例举几个常见的注解:

1、@Query,表示查询数据。具体的sql语句写在其后的大括号里面,记得要加上” “双引号。
2、@Insert,表示插入数据。(onConflict = OnConflictStrategy.REPLACE),这段表示,如果插入有冲突,就直接替换掉旧的数据。
3、@Update,表示更新数据。
4、@Delete,表示删除数据


四、如何定义一个DataBase?

@Database(entities = { User.class,dishmeal.class }, version = 2, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {

    private static final String DB_NAME = "AppDatabase.db";
    private static volatile AppDatabase instance;
    private static Context mContex = null;

    public static synchronized AppDatabase getInstance(Context context) {
        mContex = context;
        if (instance == null) {
            instance = create(context);
        }
        return instance;
    }

    private static AppDatabase create(final Context context) {
        AppDatabase database = Room.databaseBuilder(
                context,
                        AppDatabase.class,
                DB_NAME)
//                .addMigrations(MIGRATION_1_2) // , MIGRATION_2_3, MIGRATION_3_4, MIGRATION_1_4)
                .fallbackToDestructiveMigration()
                .build();

        // 获取数据库文件路径并打印
        String dbPath = context.getDatabasePath(DB_NAME).getAbsolutePath();
        Logger.d("Database path: " + dbPath);

        return database;
    }

    public static void Refdatabase()
    {
        if (instance!=null) {
            instance.close();
            instance = create(mContex);
        }

    }
    //动态设置查询条件
    public static List<dishmeal> getMealsEntities(QueryFactory queryFactory) {
        return instance.getmealDao().getMyEntities(queryFactory.createQuery());
    }
    public abstract UserDao getUserDao();
    public abstract dishmealDao getmealDao();

 

}

每一个DataBase类,都会在其类名定义的前一行,增加一个注解@Database,来标识该类是Room的一个Database。其中,entities字段,表示该DataBase,绑定的表。多个表以逗号分开。version字段,表示该DataBase的版本。

五、如何使用他们

先定义 dishmealDao对象dtMeals,再在新线程中调用dishmealDao下的方法

附件:设置动态查询条件

1)、创建接口QueryFactory,
SupportSQLiteQuery是Room数据库库在 SQLite上的抽象,它允许你构建查询并以标准的方式执行它们

public interface QueryFactory {
    SupportSQLiteQuery createQuery();
}

2)、定义MyQueryFactory 重新SupportSQLiteQuery 方法

public class MyQueryFactory implements QueryFactory {
    private String whereClause;
    private String[] whereArgs;
    private String tablename;

    public MyQueryFactory(String tablename,String whereClause, String[] whereArgs) {
        this.whereClause = whereClause;
        this.whereArgs = whereArgs;
        this.tablename=tablename;
    }

    @Override
    public SupportSQLiteQuery createQuery() {
        return new SimpleSQLiteQuery("SELECT * FROM   " + tablename + " " + whereClause, whereArgs);
    }
}

3)、在@Dao里设置动态根据查询条件,查询

@RawQuery List<dishmeal> getMyEntities(SupportSQLiteQuery query);

4)、在class AppDatabase extends RoomDatabase定义:

//动态设置查询条件

public static List<dishmeal> getMealsEntities(QueryFactory queryFactory)
{ return instance.getmealDao().getMyEntities(queryFactory.createQuery()); }

5)、应用例子:

String whereClause =" WHERE MealName like ? or MealID LIKE ? ";
String[] whereArgs = new String[]{"%水%","%2%"};//
QueryFactory queryFactory = new MyQueryFactory("meals",whereClause, whereArgs);
List<dishmeal> mlst= AppDatabase.getInstance(ShowTable.this).getMealsEntities(queryFactory);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2069134.html

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

相关文章

Selenium自动化测试 常见API的使用

本篇文章内容是关于 Selenium 自动化测试工具的常见 API 的使用 Selenium版本&#xff1a;4.23.1 编程语言&#xff1a;Java JDK22 编译器&#xff1a;IDEA 2024.2.0.2 浏览器版本&#xff1a;谷歌浏览器128.0.6613.36&#xff08;正式版本&#xff09; &#xff08;64 位&…

【Hexo】hexo-butterfly主题添加装备展示页面

本文首发于 ❄️慕雪的寒舍 在翻开往的时候看到了一位老哥的博客里面正好有这个教程&#xff0c;整了一下发现效果还不错&#xff01; Hexo的Butterfly魔改教程&#xff1a;我的装备&#xff0c;分享你在用的设备 | 张洪HeoHexo博客添加自定义css和js文件 | Leonus 注&#x…

Python个人收入影响因素模型构建:回归、决策树、梯度提升、岭回归|数据分享...

全文链接&#xff1a;https://tecdat.cn/?p37423 分析师&#xff1a;Greata Xie “你的命运早在出生那一刻起便被决定了。”这样无力的话语&#xff0c;无数次在年轻人的脑海中回响&#xff0c;尤其是在那些因地域差异而面临教育资源匮乏的年轻人中更为普遍。在中国&#xff0…

NRC-SIM:基于Node-RED的多级多核缓存模拟器

整理自&#xff1a; 《NRC-SIM: A NODE-RED Based Multi-Level, Many-Core Cache Simulator》&#xff0c;由 Ezequiel Trevio 撰写&#xff0c;作为他在德克萨斯大学里奥格兰德河谷分校攻读电气工程硕士学位的部分成果。以下是论文的详细主要内容&#xff1a; 摘要(Abstract…

全网最适合入门的面向对象编程教程:37 Python常用复合数据类型-列表和列表推导式

全网最适合入门的面向对象编程教程&#xff1a;37 Python 常用复合数据类型-列表和列表推导式 摘要&#xff1a; 在 Python 中&#xff0c;列表是一个非常灵活且常用的复合数据类型。它允许存储多个项&#xff0c;这些项可以是任意的数据类型&#xff0c;包括其他列表。列表推…

大话MoE混合专家模型

MoE&#xff08;Mixture of Experts&#xff09;&#xff0c;专家混合&#xff0c;就像是人工智能界的超级团队。想象一下&#xff0c;每个专家都有自己的拿手好戏&#xff0c;比如医疗问题找医生&#xff0c;汽车故障找机械师&#xff0c;做饭找大厨。MoE也是这样&#xff0c;…

【前端面试】操作系统

进程与线程 进程线程定义是计算机中的程序关于某数据集合上的一次运行活动&#xff0c;是系统进行资源分配和调度的基本单位是进程中的一个实体&#xff0c;是CPU调度和分派的基本单位&#xff0c;共享进程的资源资源分配拥有独立的内存空间和系统资源共享进程的内存和资源开销…

【Harmony OS 4.0】像素单位 - px、vp、fp

1. px 物理像素&#xff0c;以像素个数来定义图像尺寸。弊端是&#xff0c;在不同像素密度的屏幕上&#xff0c;相同的像素个数对应的物理尺寸是不同的。就会导致我们的应用在不同设备上显示的尺寸可能不同。如下图&#xff1a; 2. vp(Virtual Pixel) 虚拟像素是一种可根据屏幕…

L-Eval:一个60k左右长文评测数据集

前言 L-Eval是复旦大学邱锡鹏老师团队在 2023 年 7 月左右发布的一个标准化的长文本语言模型&#xff08;LCLMs&#xff09;评估数据集&#xff0c;包含20个子任务、411篇长文档、平均长度为7217个单词&#xff0c;超过2000个人工标记的QA对。它分为封闭型任务和开放型任务&am…

Niushop商城第三方插件cps联盟_同城配送_上门预约上手教程配置方法适合单商户和多商户以及V6哈

Niushop商城第三方插件cps联盟_同城配送_上门预约上手教程配置方法 序言&#xff1a;Niushop里面插件比较多可以说有上百种&#xff0c; 不过大多数都是官方自研默认自带50余种剩余的是收费的价格在80-299不等&#xff0c;另外的插件就是和第三方合作&#xff0c;简单的说就是…

25届应届网安面试,默认页面信息泄露

吉祥知识星球http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247485367&idx1&sn837891059c360ad60db7e9ac980a3321&chksmc0e47eebf793f7fdb8fcd7eed8ce29160cf79ba303b59858ba3a6660c6dac536774afb2a6330#rd 《网安面试指南》http://mp.weixin.qq.com/s?…

linux系统使用yum安装mysql5.6版本的流程

1.下载安装包及依赖包 MySQL :: Download MySQL Community Server (Archived Versions) [rootlocalhost localrepo]# ls MySQL-client-5.6.47-1.el7.x86_64.rpm MySQL-server-5.6.47-1.el7.x86_64.rpm MySQL-test-5.6.47-1.el7.x86_64.rpm MySQL-devel-5.6.47-1.…

如何关闭谷歌浏览器后台运行

当谷歌浏览器不再需要时仍处于后台运行的状态&#xff0c;这不仅消耗宝贵的系统资源&#xff0c;还会影响到多任务的处理效率。本文将为大家详细介绍关闭谷歌浏览器后台还在运行的原因&#xff0c;并提供详细步骤帮助大家禁用后台运行。&#xff08;本文由https://www.liulanqi…

【FESCO福利专区-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

无线液位变送器的特点优势

无线液位变送器集成了多种先进功能&#xff0c;广泛应用于消防水车、水厂、污水处理厂、城市供水、高楼水池、水井、水塔、地热井、矿井等领域的液位监测&#xff0c;具有以下几个显著特点&#xff1a; 4G远程通信能力&#xff1a;无线液位变送器通过内置的4G模块&#xff0c;能…

详细分析Ubuntu中的ufw基本知识

目录 前言1. 基本知识2. 基本使用 前言 由于命令行比较简单&#xff0c;此处主要以表格的形式呈现&#xff0c;还有实战中遇到的一个注意点 1. 基本知识 Ubuntu 中一种用户友好的防火墙配置工具&#xff0c;简化 iptables 的使用&#xff0c;适合那些不熟悉复杂防火墙配置的…

JAVA基础面试题总结(十四)——JVM(下)

类文件结构详解 什么是字节码&#xff1f; 在 Java 中&#xff0c;JVM 可以理解的代码就叫做字节码&#xff08;即扩展名为 .class 的文件&#xff09;&#xff0c;它不面向任何特定的处理器&#xff0c;只面向虚拟机。Java 语言通过字节码的方式&#xff0c;在一定程度上解决…

第二十八节、场景互动的逻辑实现

一、实现接口 mono后面加上接口类&#xff0c;然后实现方法 onenable在场景或物体关闭再打开的激活状态使用 二、绑定按键 三、场景转换 卸载当前场景&#xff1b;加载另一个场景&#xff1b;提供玩家的所处位置 将玩家位置粘贴过来

【Hexo】使用cloudflare pages自动化部署hexo

本文首发于 ❄️慕雪的寒舍 本文将教您使用cloudflare pages来白嫖部署hexo博客。 1.注册cloudflare 这部分就省略了&#xff0c;用邮箱注册就可以了 cloudflare pages的免费版本功能如下&#xff1a; 并发构建数&#xff1a;1&#xff08;如果有多个pages&#xff0c;同一…

搭建Windows环境下的Redis服务与TinyRDM客户端

Redis是一个开源的高性能键值对数据库&#xff0c;以其内存中数据存储和快速的读写能力而广受开发者欢迎。在Windows环境下搭建Redis服务并使用TinyRDM客户端&#xff0c;可以为开发和日常使用提供极大的便利。 安装Redis服务 1. 下载Redis安装包 首先&#xff0c;下载Redis…