前言

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/…

Room Database完全使用手册相关推荐

  1. oracle 11g rac手册(第2版) 高清,Oracle Database11g RAC手册(第2版)_IT教程网

    资源名称:Oracle Database11g RAC手册(第2版) 内容简介: 根据Oracle ACE提供的专家指导来管理动态的企业级计算基础设施.戈帕拉克里希南所著的<Oracle Dat ...

  2. 15支持哪些数据库版本 tfs_TFS数据库架构(TFS Database Architecture)

    TFS数据库架构(TFS Database Architecture) 我正在为可以使用TFS对象模型的应用程序构建后端. 到目前为止,我有一个简单的设计,有两个表. 让我们说dbo.Users ,而 ...

  3. 【Oracle 集群】Linux下Oracle RAC集群搭建之基本测试与使用(九)

    Oracle 11G RAC数据库安装(九) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总 ...

  4. oracle 拷贝文件到asm,Oracle 从ASM复制文件到文件系统

    工作中,有时需要把文件从ASM中复制到文件系统中或者反过来,做一些维护操作,本文介绍了4种复制文件的的方法:ASMCMD中的cp命令(11g) dbms_file_transfer包 rman的con ...

  5. 带有详细书签的IT电子书大全

    一.数据库书籍系列: 1.Oracle数据库系列丛书: A.Oracle数据库官方系列丛书: Oracle Database 11g初学者指南:http://download.csdn.net/det ...

  6. 闲聊Oracle Exadata与Hadoop

    在文章开始前先作个声明,本人并非专业技术人员,充其量只能算IT从业人员和技术爱好者.本文也不是写给专业技术人员看的技术类文档,只是本人因为工作需要,在学习Oracle Exadata系统架构的过程中, ...

  7. CruiseYoung提供的带有详细书签的电子书籍目录

    一.数据库书籍系列: 1.Oracle数据库系列丛书: A.Oracle数据库官方系列丛书: Oracle Database 11g初学者指南: http://download.csdn.net/de ...

  8. 有效利用Oracle官方的免费学习资源

    概述 OTN 在线产品文档用户手册 例应用实践1In-memory学习 例应用实践2动态视图定义 常用文档列表和简单介绍 白皮书White Paper 例应用实践1In-memory学习 白皮书的列表 ...

  9. 转载:数据库的相关书籍

    一.数据库书籍系列: 1.Oracle数据库系列丛书: A.Oracle数据库官方系列丛书: Oracle Database 11g初学者指南: http://download.csdn.net/de ...

最新文章

  1. 钉钉 6.0 盯上应用开发
  2. matlab 在图片上绘制热力图_python可视化之seaborn——热力图
  3. Collection集合--ArrayList源码读后感总结
  4. 实现主从关系Form中汇总行金额/数量
  5. 图书管理系统c++_校园一卡通学生如何使用,图书馆分系统演示步骤,系统间资源共享...
  6. 测试停止线程(Java)
  7. c#带参数和返回值的函数 开启线程调用的方法
  8. 数控机床属于计算机应用领域,数控技术都应用到这些领域了!你还不知道!
  9. perl语言简单入门
  10. 高等代数——大学高等代数课程创新教材(丘维声)——3.2笔记+习题
  11. Windows XP下无法安装字体的解决方案
  12. C | 使用C语言读取.mat文件
  13. 【刘文彬】【源码解读】EOS测试插件:txn_test_gen_plugin.cpp
  14. 凉面经-维恩贝特面试复盘
  15. faststone capture注册码
  16. Linux MySQL数据库的备份
  17. 龙族幻想微信一区哪个服务器人多,龙族幻想哪个区人最多_龙族幻想哪个区人多一点...
  18. crontab定时任务自动不能执行,手动可以执行的解决办法-亲测解决
  19. centos 中止 nodejs_今日热点游戏新闻!守望先锋2有望2月推出;心跳回忆新作将登陆NS;莱莎炼金工房2实体版中止发售;2K21加载画面广告...
  20. 人体动作捕捉格式BVH及其与三维坐标的转换

热门文章

  1. Windows客户端C/C++编程规范“建议”——表达式和运算
  2. CUDA Samples: green ball
  3. 【Qt】Qt样式表(Style Sheet):官网说明及例子
  4. 【Qt】ubuntu QtCreator的pro文件中使用pkg-config
  5. 【Qt】新安装的虚拟机,使用QtCreator第一次编译时报错:g++: Command not found
  6. 职称计算机 菏泽,山东菏泽2016年职称计算机首批考试时间
  7. php symfony 安装,Symfony的安装和配置方法
  8. apache mediawiki 安装_MediaWiki系统的安装、配置和修改方法(转载)
  9. python教学上机实验报告怎么写_Python基础(下)
  10. openlayers map获取全部feature_tf2.0基础-tf.data与tf.feature_column