Android Room DataBase

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 1List<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);@Insertlong insert(dishmeal meal);@Updateint update(dishmeal... meals); //动态根据查询条件,查询@RawQueryList<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;}@Overridepublic 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.mzph.cn/diannao/52393.shtml

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

相关文章

调用股票网站接口读取大A数据——个股资金流入趋势

以某股票为例&#xff0c;调用自定义的一个类&#xff0c;读取数据。 class BigAData:# 获取资金流向数据def get_money_flow(self, stock_code, page1, num20, sortopendate, asc0):该函数通过股票代码从新浪财经API获取资金流向数据。参数包括股票代码、页数、每页数量、排序…

CSS3【待总结学习】

CSS3是Cascading Style Sheets&#xff08;层叠样式表&#xff09;的第三个版本&#xff0c;它是前端开发中用于控制网页布局和样式的重要技术。CSS3在CSS2的基础上引入了众多新特性和功能&#xff0c;大大增强了网页设计和交互的能力。以下是对CSS3的详细解析&#xff1a; 一…

jenkins最佳实践(一):jenkins安装与部署

各位小伙伴们大家好呀&#xff0c;我是小金&#xff0c;下面我将记录学习jenkins的系列文章与心得&#xff0c;一方面用于博主的自我记录&#xff0c;一方面如果能帮助到正在浏览这篇文章的小伙伴&#xff0c;那更好不过了&#xff0c;本篇文章主要讲述jenkins的安装以及安装je…

Redis篇一:初识Redis

文章目录 前言1. 初始Redis2. MySQL VS Redis3. 什么是分布式系统&#xff08;也是一种处理大量数据时的处理方式&#xff09;3.1 单机架构3.2 数据库与应用服务分离3.3 负载均衡3.4 数据库读写分离3.5 引入缓存&#xff08;Redis&#xff09;3.6 数据库分库分表3.7 引入微服务…

计算机毕业设计选题推荐-OA办公管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

白酒与青年文化:潮流与传统的碰撞

在时代的洪流中&#xff0c;青年文化如同一股涌动的潮流&#xff0c;不断冲击着传统的边界。而白酒&#xff0c;作为中国传统文化的瑰宝&#xff0c;也在这一潮流中找到了新的表达方式。今天&#xff0c;我们就来探讨一下白酒与青年文化之间的碰撞与整合&#xff0c;以及豪迈白…

一文带你弄清楚基站是什么

我们每天都在通过手机、电脑等设备拨打电话和传递消息。然而&#xff0c;你是否曾深思过&#xff0c;这些来电显示和信息内容究竟是如何跨越距离&#xff0c;准确无误地从一个人传递到我们手中的呢&#xff1f;或许&#xff0c;有些细心的人已经留意到&#xff0c;在手机屏幕的…

【Vue3】编程式路由导航

【Vue3】编程式路由导航 背景简介开发环境开发步骤及源码总结 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的日…

从匿名内部类到Lambda表达式:Java编程的优雅进化

匿名内部类 首先我们先来介绍一下什么是匿名内部类 匿名内部类&#xff1a;java中一种特殊的类定义方式&#xff0c;它允许你在需要实现一个接口或继承一个类的地方直接定义一个该接口或类的匿名子类。若想创建一个派生类的对象&#xff0c;并且对象只创建一次&#xff0c;可…

微服务事务管理

1.分布式事务问题 1.1.本地事务 本地事务&#xff0c;也就是传统的单机事务&#xff0c;在传统数据库事务中&#xff0c;必须要满⾜四个原则&#xff1a; 1.2.分布式事务 分布式事务&#xff0c;就是指不是在单个服务或单个数据库架构下&#xff0c;产⽣的事务&#xff0c;例…

【Leetcode 1941 】 检查是否所有字符出现次数相同 —— 数组模拟哈希表

给你一个字符串 s &#xff0c;如果 s 是一个 好 字符串&#xff0c;请你返回 true &#xff0c;否则请返回 false 。 如果 s 中出现过的 所有 字符的出现次数 相同 &#xff0c;那么我们称字符串 s 是 好 字符串。 示例 1&#xff1a; 输入&#xff1a;s "abacbc"…

全感知、全覆盖、全智能的名厨亮灶开源了

简介 AI视频监控平台, 是一款功能强大且简单易用的实时算法视频监控系统。愿景在最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;减少企业级应用约 95%的开发成本&#xff0c;在强大视频算法加…

在Logback中配置`requestId`进行日志追踪的实践与应用

在Logback中配置requestId进行日志追踪的实践与应用 1. 引言 在分布式系统和微服务架构中&#xff0c;日志是调试、监控和性能分析的关键工具。然而&#xff0c;由于多个请求会在系统中并行处理&#xff0c;日志记录很容易变得杂乱无章&#xff0c;难以区分属于同一请求的日志…

数学基础(七)

一、熵 熵代表物体内部的混乱程度。&#xff08;一件事发生的不确定性&#xff09; 熵应用到分类任务中 二、激活函数 Sigmoid函数&#xff1a; Tanh函数&#xff1a; Relu函数&#xff1a; 三、回归分析 回归分析是寻找存在相关关系的变量间的数学表达式&#xff0c;并进行…

代码随想录算法训练营第57天|prim算法精讲、kruskal算法精讲

打卡Day57 1.prim算法精讲2.kruskal算法精讲 1.prim算法精讲 题目链接&#xff1a;prim算法精讲 文档讲解&#xff1a; 代码随想录 最小生成树是所有节点的最小连通子图&#xff0c;以最小的成本将图中所有节点连接到一起。prim算法是从节点的角度&#xff0c;采用贪心的策略…

[数据集][目标检测]电力场景输电线异物检测数据集VOC+YOLO格式2060张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2060 标注数量(xml文件个数)&#xff1a;2060 标注数量(txt文件个数)&#xff1a;2060 标注…

Spring Data JPA 中分页Pageable 的使用说明

我 | 在这里 ⭐ 全栈开发攻城狮、全网10W粉丝、2022博客之星后端领域Top1、专家博主。 &#x1f393;擅长 指导毕设 | 论文指导 | 系统开发 | 毕业答辩 | 系统讲解等。已指导60位同学顺利毕业 ✈️个人公众号&#xff1a;热爱技术的小郑。回复 Java全套视频教程 或 前端全套视频…

Android 12中读写SD卡,提示Operation not permitted问题处理

1、问题原因&#xff1a; 安卓11开始,强化了对SD卡读写的管理&#xff0c;引入了MANAGE_EXTERNAL_STORAGE权限&#xff0c;而之前的WRITE_EXTERNAL_STORAGE已经失效了。 并且MANAGE_EXTERNAL_STORAGE权限只能跳转设置页面申请。 2、解决方案 1、添加 <uses-permission an…

黑神话悟空什么配置可以玩?什么样的游戏本配置可以畅玩《黑神话:悟空》?黑神话悟空电脑配置推荐

相信不少游戏爱好者&#xff0c;近期被《黑神话&#xff1a;悟空》这款游戏刷屏了&#xff0c;预售开启不到5分钟&#xff0c;所有的产品即宣告售罄&#xff0c;预购3天销售额就破亿&#xff0c;并迅速登顶Steam全球榜。作为一款备受期待的国产3A游戏&#xff0c;以其精美的画面…

致远OA OCR票据识别组件

OCR票据识别 技术支持 技术大佬支持本文档 使用范围 任何票种信息&#xff0c;只要需要对接到oa底表中&#xff0c;就能够实现各种票种&#xff0c;各种字段的对接&#xff0c;包括票据识别&#xff0c;发票核验&#xff0c;适配各种票据 使用介绍 1 配置每种发票的ocr设…