本文整理自网络,侵删。
一、简介
Room是Google推出的Android架构组件库中的数据持久化组件库, 也可以说是在SQLite上实现的一套ORM解决方案。
Room主要包含三个部分:
- Database : 持有DB和DAO
- Entity : 定义POJO类,即数据表结构
- DAO(Data Access Objects) : 定义访问数据(增删改查)的接口
其关系如下图所示:
Room Architecture Diagram二、基本使用
1. 创建Entity
1.1 一个简单的Entitiy
一个简单Entity定义如下:
@Entity(tableName = "user" indices = {@Index(value = {"first_name", "last_name"})}) public class User { @PrimaryKey private int uid; @ColumnInfo(name = "first_name") private String firstName; @ColumnInfo(name = "last_name") private String lastName; @Ignore public User(String firstName, String lastName) { this.uid = UUID.randomUUID().toString(); this.firstName = firstName; this. lastName = lastName; } public User(String id, String firstName, String lastName) { this.uid = id; this.firstName = userName; this. lastName = userName; } // Getters and setters }
- @Entity(tableName = "table_name**") 注解POJO类,定义数据表名称;
- @PrimaryKey 定义主键,如果一个Entity使用的是复合主键,可以通过@Entity注解的primaryKeys 属性定义复合主键:@Entity(primaryKeys = {"firstName", "lastName"})
- @ColumnInfo(name = “column_name”) 定义数据表中的字段名
- @Ignore 用于告诉Room需要忽略的字段或方法
- 建立索引:在@Entity注解的indices属性中添加索引字段。例如:indices = {@Index(value = {"first_name", "last_name"}, unique = true), ...}, unique = true可以确保表中不会出现{"first_name", "last_name"} 相同的数据。
1.2 Entitiy间的关系
不同于目前存在的大多数ORM库,Room不支持Entitiy对象间的直接引用。
但Room允许通过外键(Foreign Key)来表示Entity之间的关系。
@Entity(foreignKeys = @ForeignKey(entity = User.class, parentColumns = "id", childColumns = "user_id")) class Book { @PrimaryKey public int bookId; public String title; @ColumnInfo(name = "user_id") public int userId; }
如上面代码所示,Book对象与User对象是属于的关系。Book中的user_id,对应User中的id。 那么当一个User对象被删除时, 对应的Book会发生什么呢?
@ForeignKey注解中有两个属性onDelete和onUpdate, 这两个属性对应ForeignKey中的onDelete()和onUpdate(), 通过这两个属性的值来设置当User对象被删除/更新时,Book对象作出的响应。这两个属性的可选值如下:
- CASCADE:User删除时对应Book一同删除; 更新时,关联的字段一同更新
- NO_ACTION:User删除时不做任何响应
- RESTRICT:禁止User的删除/更新。当User删除或更新时,Sqlite会立马报错。
- SET_NULL:当User删除时, Book中的userId会设为NULL
- SET_DEFAULT:与SET_NULL类似,当User删除时,Book中的userId会设为默认值
1.3 对象嵌套
在某些情况下, 对于一张表中的数据我们会用多个POJO类来表示,在这种情况下可以用@Embedded注解嵌套的对象,比如:
class Address { public String street; public String state; public String city; @ColumnInfo(name = "post_code") public int postCode; } @Entity class User { @PrimaryKey public int id; public String firstName; @Embedded public Address address; }
以上代码所产生的User表中,Column 为id, firstName, street, state, city, post_code
2. 创建数据访问对象(DAO)
@Dao public interface UserDao { @Query("SELECT * FROM user") List<User> getAll(); @Query("SELECT * FROM user WHERE uid IN (:userIds)") List<User> loadAllByIds(int[] userIds); @Query("SELECT * FROM user WHERE first_name LIKE :first AND " + "last_name LIKE :last LIMIT 1") User findByName(String first, String last); @Insert void insertAll(List<User> users); @Insert(onConflict = OnConflictStrategy.REPLACE) public void insertUsers(User... users); @Delete void delete(User user); @Update public void updateUsers(List<User> users); }
DAO 可以是一个接口,也可以是一个抽象类, Room会在编译时创建DAO的实现。
Tips:
- @Insert方法也可以定义返回值, 当传入参数仅有一个时返回long, 传入多个时返回long[]或List<Long>, Room在实现insert方法的实现时会在一个事务进行所有参数的插入。
- @Insert的参数存在冲突时, 可以设置onConflict属性的值来定义冲突的解决策略, 比如代码中定义的是@Insert(onConflict = OnConflictStrategy.REPLACE), 即发生冲突时替换原有数据
- @Update和@Delete 可以定义int类型返回值,指更新/删除的函数
DAO中的增删改方法的定义都比较简单,这里不展开讨论,下面更多的聊一下查询方法。
2.1 简单的查询
Talk is cheap, 直接show code:
@Query("SELECT * FROM user") List<User> getAll();
Room会在编译时校验sql语句,如果@Query() 中的sql语句存在语法错误,或者查询的表不存在,Room会在编译时报错。
2.2 查询参数传递
@Query("SELECT * FROM user WHERE uid IN (:userIds)") List<User> loadAllByIds(int[] userIds); @Query("SELECT * FROM user WHERE first_name LIKE :first AND " + "last_name LIKE :last LIMIT 1") User findByName(String first, String last);
看代码应该比较好理解, 方法中传递参数arg, 在sql语句中用:arg即可。编译时Room会匹配对应的参数。
如果在传参中没有匹配到:arg对应的参数, Room会在编译时报错。
2.3 查询表中部分字段的信息
在实际某个业务场景中, 我们可能仅关心一个表部分字段的值,这时我仅需要查询关心的列即可。
定义子集的POJO类:
public class NameTuple { @ColumnInfo(name="first_name") public String firstName; @ColumnInfo(name="last_name") public String lastName; }
在DAO中添加查询方法:
@Query("SELECT first_name, last_name FROM user") public List<NameTuple> loadFullName();
这里定义的POJO也支持使用@Embedded
2.3 查询结果的返回类型
Room中查询操作除了返回POJO对象及其List以外, 还支持:
相关阅读 >>
cc++qt数据库sqlrelationaltable关联表详解
微软官方sqlhelper类 数据库辅助操作类 font color=red原创font
更多相关阅读请进入《Sqlite》频道 >>

数据库系统概念 第6版
本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。