本文翻译自官网
使用Room进行持久化存储---综述
通过 Room entities 定义数据 ---Room 系列(1)
Android 中使用 Room 实践
我们可以使用 DAO (data access object 数据访问对象) 来访问数据。 一系列的 Dao 对象组成了 Room 的主要部分。每个 DAO 对象包含了访问应用中数据库的方法。
我们在使用的时候,可以将DAO 定义为一个接口或者抽象类。如果是抽象类,它可以选择带有且仅有一个 RoomDatabase 参数的构造函数。我们无需自己实现DAO , Room 将在编译时创建这个 DAO 的实现。
需要注意的是,Room 不支持在主线程中访问数据库,除非在构建的时候调用了 allowMainThreadQueries() 方法。因为在它的将是非常耗时的。
定义方法
你可以在 DAO 类中,使用很多方便的数据库操作。
Insert
当我们创建一个以 @Insert 注解的 DAO 方法的时候,Room 将在一个事务中产生一个插入它所有参数到数据库实现
@Dao
public interface MyDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List<User> friends);
}
如果 @Insert 方法仅仅接收一个参数,它可以访问一个long 类型数据,代表了插入项的 rowId。以此类推,如果参数是一个数组或者集合,返回的将是 long [] 后者 List<Long>.
Update
Update 用以通过指定参数修改 entity 。
它首先会根据 entity 的主键匹配数据,然后修改对应行的数据。
@Dao
public interface MyDao {
@Update
public void updateUsers(User... users);
}
当然,你也可以让这些方法返回一个 int 值,代表更新的行号。
Delete
Delete 代表着从数据库中删除一系列的 entity(译注:一个entity对应着数据库table中一个数据行)。它将使用主键找到那些需要被删除的 entity。
@Dao
public interface MyDao {
@Delete
public void deleteUsers(User... users);
}
Query
@Query 是 DAO 类中的主要注解。它允许在数据库中执行读写操作。
查询操作在编译的时候就已经确定了,如果这个查询是有问题的,将会发生编译错误而不用等待运行时报错。
Room 也检查了查询操作的返回值。如果返回对象的成员和相应的 列 名不匹配,Room 将通过下面两种方式给出警告:
- 给出一个相关成员不匹配的的警告
- 给出一个 error
简单的查询操作
@Dao
public interface MyDao {
@Query("SELECT * FROM user")
public User[] loadAllUsers();
}
上述是一个非常简单的查询操作,将得到所有的 User 。在编译的时候,Room 就知道它是查询所有 user 表中的列,所以如果包含一些语法错误,亦或者 user 并不存在,Room 显示报错信息。
在查询语句中添加参数
常常我们的查询都是带参数的,以进行数据过滤,比如说只找到那些年龄大于某个数值的用户。
@Dao
public interface MyDao {
@Query("SELECT * FROM user WHERE age > :minAge")
public User[] loadAllUsersOlderThan(int minAge);
}
在进行编译处理的时候,Room 会将方法中的 minAge 和 :minAge 进行匹配设置。同样,如果无法匹配(译注:比如方法中不带参数,但是上面的查询语句中却带有参数),就是显示错误信息。
当然,你也可以传递多个参数:
@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);
}
返回某些列
很多时候,我们只需要一个 entity(一个数据行) 中的某些列。举例而言,在 UI 中,你可能只需要展示用户的姓和名,而不是关于用户的所有信息。只查询必要的信息,查询完成的速度会更快。
Room 允许从查询中返回一个 Java 对象,只要这些列可以被映射为一个对象。举例而言,你可以创建一个下面的 Java 对象仅仅获取用户的姓和名:
public class NameTuple {
@ColumnInfo(name="first_name")
public String firstName;
@ColumnInfo(name="last_name")
public String lastName;
}
现在,可以在查询方法中返回这个 POJO :
@Dao
public interface MyDao {
@Query("SELECT first_name, last_name FROM user")
public List<NameTuple> loadFullName();
}
Room 可以感知到返回的 first_name 和 last_name 列中的值可以被映射到 NameTuple 类中的属性中。如果返回的太多列,或者返回的列中 NameTuple 类中并不存在这个属性,Room 会给出警告。
传递一个集合参数
有些查询操作可能需要传递的参数的个数是不确定的,只有在运行的时候才知道具体的数量。举个栗子,现在我们需要检索出某几个区域的用户信息:
@Dao
public interface MyDao {
@Query("SELECT first_name, last_name FROM user WHERE region IN (:regions)")
public List<NameTuple> loadUsersFromRegions(List<String> regions);
}
网友评论