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

本文翻译自官网
使用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);
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容