当前位置: 首页 > 编程日记 > 正文

Room Database完全使用手册

前言

Android数据持久层直接使用SQLite很麻烦,Google官方推出了Room, Google对Room的定义: The Room persistence library provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite. Room是SQLite之上的一个抽象层,通过Room层来摆脱,繁琐的数据库操作,包括创建、更新数据库、表以及进行增删查改等。

Room数据库结构

如下图,Room数据库包含三个对象:

1、Entity : 对应数据库中的表,可以使用Entity注解将一个类变成数据库中的一张表结构。

2、DAO : 全称Database Access

Object,定义了对数据库中数据的读写等操作,DAO中可以使用SQL语句来操作数据库。

3、RoomDatabase : 数据库持有类,用于创建数据库或者连接到数据库。内部包含DAO和Entity。

上面总体说了Room数据库的三个对象,下面分别介绍三个对象的作用和使用方法。

Entity

Room Database中的Entity表示一张数据表结构,一个Entity实例就是表中的一行,如定义一个Person类的Entity。

@Entity
public class Person{@PrimaryKeypublic int id;public String firstName;public String lastName;
}
复制代码

当有两个Person对象在表中时,表中的数据如下:

其中Person和Entity及数据库的关系如下所示:

重点:

1、一个Entity对象代表数据表中的一行,一个Entity类代表一张数据表。

2、Entity中的成员变量都是数据表中的列。

3、一个Java类定义成Entity只要加上Entity注解就可以了。

Entity的使用

1、定义一个Entity

@Entity(tableName = "person_table")
public class Person{@PrimaryKeypublic int id;public String firstName;public String lastName;
}
复制代码

如果想给Entity命名可以在@Entity注解的后面加上(tableName = "person_table"),如果不加会使用默认命名,上面的id,firstName, lastName都定义成了public类型,是为了数据库能够有操作这些数据的权限,也可以选择将这些都设置成private类型,然后通过setter和getter来操作。

2、定义主键

每一个Entity至少定义一个主键(primary key),哪怕Entity中只有一个变量也要将这个变量定义为主键,在Room数据库中使用注解 @PrimaryKey 来定义主键,@PrimaryKey 的使用方式有两种一种是在类变量前面加,如果主键比较复杂可以加在@Entity注解的后面。

@Entity(primaryKeys = {"firstName", "lastName"})
public class User {public String firstName;public String lastName;
}
复制代码

3、改变属性列名

和改变表名称tableName一样,可以改变表中的列名称,使用 @ColumnInfo来改变列的名称。如果不改的话默认使用变量名的小写形式。

@Entity(tableName = "person_table")
public class Person {@PrimaryKeypublic int id;@ColumnInfo(name = "first_name")public String firstName;@ColumnInfo(name = "last_name")public String lastName;
}
复制代码

4、使某些变量不生成数据表中的字段

由上面可知当一个类前加了Entity注解后类中的所有成员变量都会生成表中的属性列,如果我们不希望某个变量生成表中的属性列,可以使用注解 @Ignore。

@Entity
public class Person {@PrimaryKeypublic int id;public String firstName;public String lastName;@IgnoreBitmap picture;
}
复制代码

如果有类继承上面的Person类,并且不想picture生成数据表中的列,那么可以ignoredColumns

@Entity(ignoredColumns = "picture")
public class RemotePerson extends Person {@PrimaryKeypublic int id;public boolean hasVpn;
}
复制代码

5、两个数据表关联

SQLite是关系数据库,可以明确两个对象间的关系,大多数的关系数据库都可以指定表之间的关联,但是Room数据库不能够之间指定两个表之间的关系,但是可以通过@ForeignKey注解来进行表的关联。

@Entity(foreignKeys = @ForeignKey(entity = Person.class,parentColumns = "id",childColumns = "user_id"))
public class Book {@PrimaryKeypublic int bookId;public String title;@ColumnInfo(name = "user_id")public int userId;
}
复制代码

6、嵌套Entity

如果定义的Entity类里面有个对象,并且希望定义的Entity中的表列字段包含Entity类对象中的变量,可以在Entity类对象中加@Embedded标注。

public class Address {public String street;public String state;public String city;@ColumnInfo(name = "post_code")public int postCode;
}@Entity
public class Person{@PrimaryKeypublic int id;public String firstName;@Embeddedpublic Address address;
}
复制代码

这样Person表中的列字段有id, firstName, street, state, city,和 post_code.

DAO

在DAO(data access object)中,可以使用SQL语句进行对数据库的操作并且将这些语句与Java中方法关联调用,编译器会检查SQL语句并且通过注解生成对应的查询语句,例如@Insert。

注意:

1、DAO必现是抽象类或者接口

2、所有的查询语句必须在单独的线程里面执行。

DAO的使用

可以使用sql中的语句来实现DAO的操作。

1、插入数据

当在方法前使用@Insert注解时,Room数据库会将方法中的所有参数都插入到数据表中。

@Dao
public interface MyDao {@Insert(onConflict = OnConflictStrategy.REPLACE)public void insertUsers(User... users);@Insertpublic void insertBothUsers(User user1, User user2);@Insertpublic void insertUsersAndFriends(User user, List<User> friends);
}
复制代码

当@Insert 方法只插入一个参数时,插入会返回long数据代表插入的对象在数据表中的行号,当插入一个数组或者集合形式的数据时,会返回long数组或者集合。 2、更新数据

@Update标注的方法会查找表中与所给数据主键一样的数据进行更新。

@Dao
public interface MyDao {@Updatepublic void updateUsers(User... users);
}
复制代码

3、查询数据

@Query 标注的查询方法是使用最多的方法,每个查询方法在编译期间就会被验证是否正确,如果错误就会报错,不会在运行时再提示失败。在

@Dao
public interface MyDao {@Query("SELECT * FROM user")public User[] loadAllUsers();
}
复制代码

如果存在查询语法错误,或者数据库中不存在user表,Room数据库会在编译时提示错误信息。 也可以使用SQL语句实现复杂的查询

@Dao
public interface MyDao {@Query("SELECT * FROM user WHERE age BETWEEN :minAge AND :maxAge")public User[] loadAllUsersBetweenAges(int minAge, int maxAge);@Query("SELECT * FROM user WHERE first_name LIKE :search " +"OR last_name LIKE :search")public List<User> findUserWithName(String search);
}
复制代码

4、查询列表中的数据并返回子列表

有时候并不需要将查询数据的所有字段都返回,大部分时候只需要返回查询数据的一个子域。下面实现返回查询的一个子域。

public class NameTuple {@ColumnInfo(name = "first_name")public String firstName;@ColumnInfo(name = "last_name")public String lastName;
}
复制代码

然后查询返回子域中的字段

@Dao
public interface MyDao {@Query("SELECT first_name, last_name FROM user")public List<NameTuple> loadFullName();
}
复制代码

RoomDatabase

上面已经介绍了DAO和Entity,Entity定义表,DAO定义对表中数据进行操作,RoomDatabase包含了DAO,并且提供创建和连接数据库的方法。

创建Room database

创建Room database包括三个步骤: 1、创建继承RoomDatabase的抽象类。

2、在继承的类前使用注解@Database。

3、申明数据库结构的Entity,并且设置数据库的版本号。

@Database(entities = {Word.class}, version = 1)//申明Entity和数据库的版本号
public abstract class WordRoomDatabase extends RoomDatabase { public abstract WordDao wordDao();//创建DAO的抽象类private static WordRoomDatabase INSTANCE;//创建单例static WordRoomDatabase getDatabase(final Context context) {if (INSTANCE == null) {synchronized (WordRoomDatabase.class) {if (INSTANCE == null)    {INSTANCE = Room.databaseBuilder(context.getApplicationContext(),WordRoomDatabase.class, "word_database").addCallback(sOnOpenCallback).fallbackToDestructiveMigration().build();                }}}return INSTANCE;}private static RoomDatabase.Callback sOnOpenCallback =new RoomDatabase.Callback(){@Overridepublic void onOpen (@NonNull SupportSQLiteDatabase db){super.onOpen(db);initializeData();}};}
复制代码

注意: 1、编译时会检查SQL语句是否正确

2、不要在主线程中进行数据库操作

3、RoomDatabase最好使用单例模式

最后上一张Android在使用Room数据库时和Room数据库交互的图

application从RoomDatabase中获取DAO实例,并且通过DAO中定义的方法来操作数据库中Entity。获取设置entity的数据。

Room database Migration

当升级Android应用的时候,有时需要更改数据库中数据的结构,要用户升级应用的时候保持原有的数据不变,使用数据库移植Migration是必须的。在Room数据库中Room persistence library库提供了升级数据库时保存用户数据的方法。 使用方法 定义Migration对象,每个对象包含数据库的开始版本号和结束版本号。

    static final Migration MIGRATION_1_2 = new Migration(1, 2) {@Overridepublic void migrate(SupportSQLiteDatabase database) {//这里面实现更改数据表结构的方法}};
复制代码

如上实现一个Migration对象,重写migrate方法,在migrate方法中实现升级时要进行的操作。

    static final Migration MIGRATION_2_3 = new Migration(2, 3) {@Overridepublic void migrate(SupportSQLiteDatabase database) {database.execSQL("ALTER TABLE users "+ " ADD COLUMN last_update INTEGER");}};
复制代码

如果我们数据库要从版本1,升级到版本库,就要定义MIGRATION_1_2 ,MIGRATION_2_3 ,MIGRATION_3_4 ,MIGRATION_1_4 并且改写单例方法。

    public static UsersDatabase getInstance(Context context) {synchronized (sLock) {if (INSTANCE == null) {INSTANCE = Room.databaseBuilder(context.getApplicationContext(),UsersDatabase.class, "Sample.db").addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_1_4).build();}return INSTANCE;}}
复制代码

当然不一定非要定义MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_1_4这么多,也可以一次从MIGRATION_1_4,跳过中间的MIGRATION,但是如果不提供足够的MIGRATION,从当前版本变到最新版本,Room数据库会清楚原来的数据重写创建。

参考文献

1、developer.android.com/training/da…

2、codelabs.developers.google.com/codelabs/an…

我的csdn

blog.csdn.net/u013309870/…

相关文章:

wiki的使用

Wiki一词来源于夏威夷语的”weekee wee kee”&#xff0c;被译为”维基”或”维客”。Wiki是一种多人协作的写作编辑平台。在Wiki网站上&#xff0c;访问者可以修改、完善已经存在的页面&#xff0c;或者创建新内容。 可以利用”维基百科&#xff1a;沙盒”来练习如何编辑&…

GAMIT安装备忘

2019独角兽企业重金招聘Python工程师标准>>> 系统环境&#xff1a; VMware Workstation9 ubuntu 10.04 操作 1.安装VMware Workstation 参考&#xff1a; VMware Workstation下载&#xff1a;http://pan.baidu.com/share/link?shareid407480&uk258569718…

FreeType简介及在vs2010的编译使用

FreeType库是一个开源、高质量、可扩展、可定制、可移植的字体引擎&#xff0c;它提供统一的接口来访问多种字体格式文件&#xff0c;包括点阵字、TrueType、OpenType、Type1、CID、CFF、Windows FON/FNT、X11 PCF等。 FreeType有两个License&#xff0c;一个是BSD-stype&…

firefox下的调试工具

2019独角兽企业重金招聘Python工程师标准>>> vue-devtools https://addons.mozilla.org/en-US/firefox/user/13100848/ 转载于:https://my.oschina.net/u/3371661/blog/3003299

NLP为RPA带来了什么价值?

什么是 RPA&#xff08;Robotic Process Automation&#xff09;&#xff1f;机器人流程自动化&#xff08;RPA&#xff09;是一种自动化工具&#xff0c;用于创建软件机器人的虚拟劳动力&#xff0c;从而优化和降低企业中端到端业务流程的成本。RPA 可以翻译成机器人流程自动化…

从原理到代码,轻松深入逻辑回归模型!

整理 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;【导语】学习逻辑回归模型&#xff0c;今天的内容轻松带你从0到100&#xff01;阿里巴巴达摩院算法专家、阿里巴巴技术发展专家、阿里巴巴数据架构师联合撰写&#xff0c;从技术原理、算法和工程…

JVM内存管理学习总结(一)

I.JVM进程的生命周期 JVM实例的生命周期和java程序的生命周期保持一致&#xff0c;即一个新的程序启动则产生一个新的JVM进程实例&#xff0c;程序结束则JVM进程实例伴随着消失。那么程序启动和程序终止就是JVM实例生命周期的两个边界&#xff0c;两个边界点可以这么理解&#…

开源库Simd在vs2010中的编译及简单使用

Simd是开源的图像处理库&#xff0c;它提供了很多高性能的算法&#xff0c;这些优化算法主要由SIMD指令来实现&#xff0c;包括SSE、SSE2、SSSE3、SSE4.1、SSE4.2、AVX等&#xff0c;此库可以应用在windows/linux 32bit/64bit等系统中。此库更新较频繁。此库的license是MIT。下…

Dubbo2.6.5+Nacos注册中心(代替Zookeeper)

在上一节的小栗子的基础上&#xff0c;只需要更改两个地方 第一个&#xff1a;父工程的pom依赖增加 <!-- Dubbo Nacos registry dependency --><dependency><groupId>com.alibaba</groupId><artifactId>dubbo-registry-nacos</artifactId>…

Nginx(二) 配置与调试

nginx 主配置文件在安装目录下的conf中&#xff0c;名字为nginx.conf&#xff1a;主配置文件主要分为4部分&#xff1a;main&#xff08;全局设置&#xff09;、server&#xff08;主机设置&#xff09;、upstream&#xff08;负载均衡服务器设置&#xff09;和location&#x…

AI编程语言图鉴

作者 | 元宵大师责编 | 胡巍巍来源 | CSDN&#xff08;CSDNnews&#xff09;当前最炙手可热的领域非“人工智能”&#xff08;Artificial Intelligence&#xff09;莫属。其实&#xff0c;“人工智能”的火热并非一蹴而就&#xff0c;早在1956年“人工智能”概念就已经被提出了…

C++动态二维数组演示的代码

将代码过程中经常用到的代码珍藏起来&#xff0c;下边资料是关于C动态二维数组演示的代码。 #include <iostream> #include <string>using namespace std;{for( int i 0; i < x; i ){List[i] new int[y];for( int j 0; j < y; j ){List[i][j] 0;}}for( i…

linux发送email错误 501 Syntax: HELO hostname

2019独角兽企业重金招聘Python工程师标准>>> 查看你的hostname hostnamecentos58 然后vi /etc/hosts 添加hostname对应的ip 103.24.3.171 centos58 参考http://blog.csdn.net/tammy_zhu/article/details/5563383 转载于:https://my.oschina.net/u/257088/bl…

redux-thunk使用教程

从无到有一步一步创建一个react-redux、redux-thunk使用教程&#xff1a;本教程GitHub地址&#xff1a;https://github.com/chunhuigao/react-redux-thunk创建react工程在电脑上找一个文件夹&#xff0c;在命令窗使用create-react-app 创建我的react工程&#xff1b;这一步应该…

VLC SDK在VS2010中的配置及简单使用举例

1. 从http://www.videolan.org/vlc/download-windows.html下载vlc-2.2.0-win32.7z&#xff0c;解压缩&#xff1b;2. 新建一个VLCtest控制台工程&#xff1b;3. 将/vlc-2.2.0-win32/vlc-2.2.0/sdk/include添加到工程属性中&#xff0c;C/C -->General …

百万奖金悬赏AI垃圾分类,就问你来不来?

也许我们从来没有想过&#xff0c;看似简单的垃圾分类居然给“聪明”的人类带来如此大的困扰2019年7月1日&#xff0c;史称“最严格的垃圾分类法”《上海市生活垃圾管理条例》正式开始施行一夜之间上海人最常用的见面语从“侬好”变成了“侬是什么垃圾&#xff1f;”虽然只有可…

资质申报 - 系统集成企业资质等级评定条件(2012年修定版)

关于发布《计算机信息系统集成企业资质等级评定条件&#xff08;2012年修定版&#xff09;》的通知工信计资&#xff3b;2012&#xff3d;6号各省、自治区、直辖市、计划单列市工业和信息化主管部门、新疆生产建设兵团工业和信息化委员会、各级资质评审机构&#xff0c;各有关单…

@HostListener 可接收的事件列表

下面有一个文档详细介绍Angular 中的事件列表&#xff1a; https://github.com/angular/angular/blob/master/packages/compiler/src/schema/dom_element_schema_registry.ts#L78。 星号代表的是事件 (no prefix): property is a string.*: property represents an event.!: pr…

GraphSAGE: GCN落地必读论文

作者 | William L. Hamilton, Rex Ying, Jure Leskovec来源 | NIPS17导读&#xff1a;图卷积网络&#xff08;Graph Convolutional Network&#xff0c;简称GCN&#xff09;最近两年大热&#xff0c;取得不少进展。作为 GNN 的重要分支之一&#xff0c;很多同学可能对它还是一知…

Ubuntu14.04 32位上编译VLC2.2.0源码操作步骤

1. 首先安装必须的依赖软件&#xff0c;打开终端&#xff0c;执行&#xff1a;sudo apt-get install git libtool build-essential pkg-config autoconf2. 从 http://www.videolan.org/vlc/download-sources.html 下载vlc-2.2.0源码&#xff0c;将其存放到/home/spring/VLC目录…

根据PromiseA+规范实现Promise

Promise是ES6出现的一个异步编程的一个解决方案&#xff0c;改善了以往回调函数的回调地狱(虽然写起来也挺像的)。不会Promise的可以移步阮一峰的Promise&#xff0c;这里讲的非常清晰。 就现在的发展情况而言&#xff0c;Promise这种解决方案频繁的在我们的代码中出现&#xf…

黄浴:基于深度学习的超分辨率图像技术发展轨迹一览

作者 | 黄浴转载自知乎导读&#xff1a;近年来&#xff0c;使用深度学习技术的图像超分辨率&#xff08;SR&#xff09;取得了显著进步。本文中&#xff0c;奇点汽车自动驾驶首席科学家黄浴对基于深度学习技术的图像超分辨率技术进行了一次全面的总结&#xff0c;分析了这门技术…

Qt简介、安装及在Ubuntu14.04 32位上简单使用举例

Qt是一个跨平台的C图形用户界面应用程序开发框架。它既可以开发GUI程序&#xff0c;也可用于开发非GUI程序。Qt是面向对象的框架&#xff0c;很容易扩展。Qt是一个C工具包&#xff0c;它由几百个C类构成&#xff0c;你在程序中可以使用这些类。Qt具有OOP的所有优点。 跨平台的…

FOSCommentBundle功能包:设置Doctrine ODM映射(投票)

原文出处&#xff1a;12b-mapping_mongodb.md原文作者&#xff1a;FriendsOfSymfony授权许可&#xff1a;创作共用协议翻译人员&#xff1a;FireHare校对人员&#xff1a;适用版本&#xff1a;FOSCommentBundle 2.0.5文章状态&#xff1a;草译阶段Step 12b: Setup MongoDB mapp…

Python最大堆排序实现方法

Python最大堆排序实现方法&#xff0c;具体代码如下&#xff1a; # -*- coding: utf-8 -*- def merge_sort(seq, cmpcmp, sentinelNone): """合并排序&#xff0c;伪码如下&#xff1a; MERGE(A, p, q, r) 1 n1 ← q - p 1 // 前个子序列长度 2 …

内含福利 | 世界人工智能大会:对话大咖,深挖机器学习的商业应用

机器学习作为人工智能时代的关键技术突破&#xff0c;已经在日常生活中广泛应用&#xff0c;给用户带来便利。越来越多的企业也通过机器学习&#xff0c;解决生产和经营中的难题。传统制造业&#xff1a;应用机器学习&#xff0c;部署系统异常检测方案&#xff0c;预测组件寿命…

windows7 64位操作系统上使vs2010和vs2013能够并存的处理方法

之前机子上是只安装有vs2010&#xff0c;后来在没有卸载vs2010的情况下想装个vs2013,使vs2010与vs2013同时并存在windows764位机上。需要依次安装cn_visual_studio_ultimate_2013_x86_dvd_3009109.iso、vs2013.2.iso和vc_mbcsmfc.exe。在安装过程中遇到的问题有&#xff1a; (…

Spring Cloud Alibaba 基础教程:Nacos 生产级版本 0.8.0

Spring Cloud Alibaba 基础教程&#xff1a;Nacos 生产级版本 0.8.0 昨晚Nacos社区发布了第一个生产级版本&#xff1a;0.8.0。由于该版本除了Bug修复之外&#xff0c;还提供了几个生产管理非常重要的特性&#xff0c;所以觉得还是有必要写一篇讲讲这次升级&#xff0c;在后续的…

awk命令使用和取出数据的最大值,最小值和平均值

得到取出数据的最大值&#xff1a;cat manager.txt |grep monitor|awk {print$9}|sort -rn|head -1得到取出数据的最小值&#xff1a;cat manager.txt|grep monitor |awk {print $9}|sort -n|head -1得到取出数据的平均值&#xff1a;cat manager.txt|grep monitor |awk {print…

windows7 64位机上CUDA7.0配置及在VS2010中的简单使用举例

1. 查看本机配置&#xff0c;查看显卡类型是否支持NVIDIA GPU&#xff0c;选中计算机--> 右键属性 --> 设备管理器 --> 显示适配器&#xff1a;NVIDIA GeForce GT 610&#xff0c;从https://developer.nvidia.com/cuda-gpus可以查到相应显卡的compute capabili…