美文网首页开源库
[译] 使用 Room 的 DAO 访问数据---Room 系列

[译] 使用 Room 的 DAO 访问数据---Room 系列

作者: 风雪围城 | 来源:发表于2017-12-17 21:19 被阅读0次

    本文翻译自官网
    使用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);
    }
    

    相关文章

      网友评论

        本文标题:[译] 使用 Room 的 DAO 访问数据---Room 系列

        本文链接:https://www.haomeiwen.com/subject/unzzixtx.html