目录

一、概述

1.1 描述

1.2 主要部件

二、创建 Room

2.1 添加依赖项

2.2 创建数据实体

2.2.1 设置 tableName or name 属性

2.2.2 设置主键

2.2.3 忽略字段

2.3 创建数据访问对象 (DAO)

2.4 创建数据库

三、使用 Room

3.1 创建数据库

3.2 添加数据

3.3 查找数据

3.4 修改数据

3.5 删除数据

四、相关链接


一、概述

1.1 描述

上文介绍到了SQLite Api,今天咱们介绍一下 Room ( Android Jetpack 重要成员之一 )。

        Room 持久性库在 SQLite 之上提供了一个抽象层,以允许流畅的数据库访问,同时利用 SQLite 的全部功能。特别是,Room 提供以下好处:

  • SQL 查询的编译时验证。

  • 方便的注释,最大限度地减少重复和容易出错的样板代码。

  • 简化的数据库迁移路径。

由于这些考虑,我们强烈建议您使用 Room 而不是直接使用 SQLite API。

1.2 主要部件

Room 包含三个主要组件:

  • 保存数据库并用作与应用程序持久数据的底层连接的主要访问点的数据库类

  • 表示应用数据库中表的数据实体

  • 数据访问对象(DAO),提供你的应用可用于在数据库中查询、更新、插入和删除数据的方法。

数据库类为您的应用程序提供与该数据库关联的 DAO 实例。反过来,应用程序可以使用 DAO 从数据库中检索数据作为关联数据实体对象的实例。该应用程序还可以使用定义的数据实体来更新相应表中的行,或创建新行以进行插入。下图说明了 Room 不同组件之间的关系。

二、创建 Room

2.1 添加依赖项

在 app/build.gradle文件中添加依赖:

dependencies {//Roomdef room_version = "2.4.1"implementation "androidx.room:room-runtime:$room_version"annotationProcessor "androidx.room:room-compiler:$room_version"
}

2.2 创建数据实体

将每个 Room 实体定义为一个使用 @Entity 注释的类。 Room 实体包括数据库中对应表中每一列的字段,包括一个或多个构成主键的列。因此,实体类往往是不包含任何逻辑小型模型类。我们的 User 类代表数据库中数据的模型,告诉 Room 它应该基于这个类创建一个表:

@Entity
public class User {@PrimaryKeypublic int id;public String mName;public int mAge;
}

通过将 @PrimaryKey 注释添加到正确的字段来设置主键(如:id)。

注意:要保留一个字段,Room 必须有权访问它。 你其设为 public 或为其提供 getter 和 setter 方法来确保 Room 可以访问该字段。

默认情况下:

  • 数据库表名:Room 使用类名作为数据库表名。或通过 @Entity 注释的 tableName 属性来设置表的名称。

  • 列名:Room 默认使用字段名作为数据库中的列名。或通过 @ColumnInfo 注释添加到字段并设置 name 属性来修改列名。

2.2.1 设置 tableName or name 属性

@Entity(tableName = "users")
public class User {@PrimaryKeypublic int id;@ColumnInfo(name = "name")public String mName;@ColumnInfo(name = "age")public int mAge;
}

此时我们将表名设置为 users 。将 mName 和 mAge 在表中的列名分别修改为 name 和 age。

注意:SQLite 中的表名和列名不区分大小写。

2.2.2 设置主键

1、定义单主键

        每个 Room 实体必须定义一个主键,用于唯一标识相应数据库表中的每一行。最直接的方法是使用 @PrimaryKey 注释单个列,如上面 User 类中的 id 属性

注意:如果你需要 Room 为实体实例分配自动 ID,请将 @PrimaryKey 的 autoGenerate 属性设置为 true

@Entity(tableName = "users")
public class User {@PrimaryKey(autoGenerate = true)public int id;
}

2、定义复合主键

如果你需要通过多个列的组合来唯一标识实体的实例,你可以通过在 @Entity 的 primaryKeys 属性中列出这些列来定义复合主键:

@Entity(tableName = "users",primaryKeys = {"mName","mAge"})
public class User {public String mName;public int mAge;
}

2.2.3 忽略字段

默认情况下,Room 为实体中定义的每个字段创建一个列。但是某些字段我们不需要保存到数据库,可以使用@Ignore 对其进行注释。

@Entity(tableName = "users")
public class User {@Ignore      //@Ignore 此属性不在数据库生产列public String nickname;
}

2.3 创建数据访问对象 (DAO)

DAO 负责定义访问数据库的方法。使用 Room,我们不需要所有与 Cursor 相关的代码,只需使用 UserDao 类中的注释定义我们的查询即可。每个 DAO 都包含提供对应用程序数据库的抽象访问的方法在编译时,Room 会自动生成您定义的 DAO 的实现

你可以将 DAO 定义为接口或抽象类。对于基本用例,通常应该使用接口。无论哪种情况,都必须使用 @Dao 注释你的 DAO。DAO 没有属性,但它们确实定义了一种或多种方法来与应用程序数据库中的数据进行交互。

@Dao //这个是必须的
public interface UserDao {//无需编写任何 SQL 代码即可在数据库中插入、更新和删除行的便捷方法。//新增单个实体@Insertvoid insertUser(User user);//新增多个实体@Insertvoid insertUsers(List<User> users);//更新数据@Updatevoid updateUser(User user);//删除数据@Deletevoid deleteUser(User user);//编写自己的 SQL 查询(query)方法//查询 users 表@Query("SELECT * FROM users")List<User> getAll();//根据name查询 users 表,将参数集合传递给查询@Query("SELECT * FROM users WHERE name IN (:usernames)")List<User> loadAllByNames(int[] usernames);//将简单参数传递给查询@Query("SELECT * FROM users WHERE age > :minAge")public User[] loadAllUsersOlderThan(int minAge);
}

2.4 创建数据库

定义一个 AppDatabase 类来保存数据库。AppDatabase 定义数据库配置并充当应用程序对持久数据的主要访问点。数据库类必须满足以下条件:

  • 该类必须使用 @Database 注释进行注释,该注释包括一个实体数组,该数组列出了与数据库关联的所有数据实体。

  • 该类必须是扩展 RoomDatabase 的抽象类。

  • 对于与数据库关联的每个 DAO 类,数据库类必须定义一个具有零参数并返回 DAO 类实例的抽象方法。

import androidx.room.Database;@Database(entities = {User.class},version = 1)
public abstract class AppDatabase {public abstract UserDao userDao();
}

Room 的三个主要组件已经创建好了,咱们开始使用吧。

三、使用 Room

3.1 创建数据库

数据库保存路径:/data/data/com.scc.datastorage/files/room_db

注意:数据库的操作一定要放到子线程中,切不可在主线程中操作(否则会报错),虽然可以强制开启允许这么做,但不要在主线程中操作数据库,避免遇到ANR问题。

            //创建数据库String dir = getFilesDir() + "/room_db";AppDatabase db = Room.databaseBuilder(AppGlobalUtils.getApplication(),AppDatabase.class, dir).build();

允许在主线程中进行数据库操作:

在构建AppDatabase实例的时候,添加allowMainThreadQueries()方法,这样Room就可以在主线程中进行数据库操作了,但是这个方法只建议在测试环境下使用

        db = Room.databaseBuilder(AppGlobalUtils.getApplication(),AppDatabase.class, dir).allowMainThreadQueries().build();

3.2 添加数据

            List<User> list = new ArrayList<>();list.add(new User(10, "帅次次", 20, "09:00"));list.add(new User(12, "朱元璋", 30, "11:00"));list.add(new User(15, "赵匡胤", 40, "13:00"));list.add(new User(18, "李世民", 50, "15:00"));new Thread(() -> {userDao.insertUsers(list);Log.e("Room", "插入成功:" + db.userDao().queryAll().size());}).start();

3.3 查找数据

            new Thread(() -> {StringBuilder sql = new StringBuilder();List<User> list = userDao.queryAll();sql.append(list.size());if (list.size() > 0) {for (User bean : list) {sql.append("\n").append(bean.toString());}}Log.e("Room", sql.toString());}).start();

3.4 修改数据

            new Thread(() -> {StringBuilder sql = new StringBuilder();List<Integer> id = new ArrayList<>();id.add(18);List<User> list = db.userDao().queryAllById(id);if (list.size() > 0) {sql.append("\n 修改数据前:").append(list.get(0).toString());}User user = new User(18, "武媚娘", 32, "12:00");userDao.updateUser(user);list = db.userDao().queryAllById(id);if (list.size() > 0) {sql.append("\n 修改数据后:").append(list.get(0).toString());}Log.e("Room", String.valueOf(sql));}).start();

3.5 删除数据

                new Thread(() -> {StringBuilder sql = new StringBuilder();List<User> list = userDao.queryAll();if (list.size() > 0) {for (User bean : list) {sql.append("\n").append(bean.toString());}}User user = new User();user.id = 12;db.userDao().deleteUser(user);sql.append("\n删除后");List<User> listDelete = db.userDao().queryAll();Log.e(getClass().getName(), "list:" + list.size());if (listDelete.size() > 0) {for (User bean : listDelete) {sql.append("\n").append(bean.toString());}}Log.e("Room", sql.toString());}).start());

然后你会发现 Room 和 SQLite的用法基本一致。操作简单易上手,说试试就试试。

四、相关链接

Android 数据全方案处理

Android 数据存储(四)-Room相关推荐

  1. Android数据的四种存储方式SharedPreferences、SQLite、Content Provider和File (四) —— ContentProvider...

    ContentProvider是安卓平台中,在不同应用程序之间实现数据共享的一种机制.一个应用程序如果需要让别的程序可以操作自己的数据,即可采用这种机制.并且此种方式忽略了底层的数据存储实现,Cont ...

  2. Android数据的四种存储方式

    很清晰的思路,转自Android数据的四种存储方式 作为一个完成的应用程序,数据存储操作是必不可少的.因此,Android系统一共提供了四种数据存储方式.分别是:SharePreference.SQL ...

  3. < Android数据存储> 任务二 应用程序数据文件夹里的文件读写

    :zh]Android中提供了两个方法用来打开应用程序的数据文件夹IO流. 1.FileInputStream openFileInput(String name):参数name表示某个文件名,该方法 ...

  4. 5 Android数据存储 任务二 应用程序数据文件夹里的文件读写 ,

    Android中提供了两个方法用来打开应用程序的数据文件夹IO流. 1.FileInputStream openFileInput(String name):参数name表示某个文件名,该方法用于打开 ...

  5. android+默认存储,Android 数据存储之SP存储,内部存储,外部存储

    Android 数据存储之SP存储,内部存储,外部存储 Android提供了多种数据存储的技术来永久的保存应用数据,以便于开发者能够根据自己的需求来选择合适的数据存储方案,主要有SharedPrefe ...

  6. Android数据存储几种方式用法总结

    Android数据存储几种方式用法总结 1.概述 Android提供了5种方式来让用户保存持久化应用程序数据.根据自己的需求来做选择,比如数据是否是应用程序私有的,是否能被其他程序访问,需要多少数据存 ...

  7. Android 数据存储 利用SQLiteDatabase实现简单的学生管理

    转载请注明出处:明桑Android 这是作为上一篇Android 数据存储 如何搞定SQLite Database的实例练习,之所以单独列出来是因为除了数据库方面的知识,还涉及其它方面的知识,所以就写 ...

  8. Android数据存储——2.文件存储_B_资源文件

    今天学习Android数据存储--文件存储_资源文件 把资源文件mybook.txt放入项目目录下的res资源文件夹下的raw文件夹下(没有则新建),PS:mybook.txt存为UTF-8编码. X ...

  9. Android数据存储——2.文件存储_C_DOM解析XML文档

    今天学习Android数据存储--文件存储_DOM解析XML文档 位于org.w3c.dom操作XML会比较简单,就是将XML看做是一颗树,DOM就是对这颗树的一个数据结构的描述,但对大型XML文件效 ...

  10. Android数据存储之GreenDao 3.0 详解

    前言: 今天一大早收到GreenDao 3.0 正式发布的消息,自从2014年接触GreenDao至今,项目中一直使用GreenDao框架处理数据库操作,本人使用数据库路线 Sqlite----> ...

最新文章

  1. python 每分钟运行一次_调度Python脚本以准确地每小时运行一次
  2. css input光标粗细,如何用CSS原生属性caret-color改变input输入框光标颜色
  3. android SharedPreferences保存list数据
  4. 使用JGit API探索Git内部
  5. uva 11995——I Can Guess the Data Structure!
  6. python怎么放音乐_python怎么播放音乐
  7. 搞不定的C语言--static的作用
  8. ICLR 审稿人:这篇论文在标签平滑和知识蒸馏的关系上取得了重大突破!
  9. php mysql随机抽奖源码_PHP随机按百分比抽奖
  10. android实现横向选择器,安卓开发 简单实现自定义横向滚动选择View : HorizontalselectedView...
  11. fastText训练集对比,分词与句子
  12. linux 设置深信服easyconnect 代理
  13. Unity3D 的LookAt() 与 LookRotation()方法的比较
  14. Mining Hero於ETHDenver峰會提交專案,整合IPFS應用場景
  15. db与放大倍数的转化
  16. Selenium学习 - 简介
  17. 记腾讯的暑期实习面试
  18. 【阿里云】DCDN全站加速介绍及配置
  19. 用C语言程序实现十进制转换为二进制
  20. 对话美团 CEO 王兴:太多人关注边界,而不关注核心

热门文章

  1. IJCAI2022推荐系统论文集锦
  2. Vscode连接远程服务器出现‘Acquiring lock on/home/~’问题
  3. MySQL5.6 GTID
  4. linux下socket编程常用头文件
  5. 朱光潜给青年的十二封信 之 谈升学和选课
  6. 网页隐藏密码查看方法
  7. 投射数据卷Secret、ConfigMap、DownwardAPI
  8. 免费压缩视频大小最佳方法?
  9. Yii2 第三方类库安装和使用:Imagine
  10. 超硬核的Java学习路线图(宫斗版)一般程序员一看就懂