[譯] 使用 Room 的 DAO 訪問數(shù)據(jù)---Room 系列(2)

本文翻譯自官網(wǎng)
使用Room進(jìn)行持久化存儲(chǔ)---綜述
通過 Room entities 定義數(shù)據(jù) ---Room 系列(1)
Android 中使用 Room 實(shí)踐
我們可以使用 DAO (data access object 數(shù)據(jù)訪問對(duì)象) 來訪問數(shù)據(jù)。 一系列的 Dao 對(duì)象組成了 Room 的主要部分。每個(gè) DAO 對(duì)象包含了訪問應(yīng)用中數(shù)據(jù)庫(kù)的方法。

我們?cè)谑褂玫臅r(shí)候,可以將DAO 定義為一個(gè)接口或者抽象類。如果是抽象類,它可以選擇帶有且僅有一個(gè) RoomDatabase 參數(shù)的構(gòu)造函數(shù)。我們無需自己實(shí)現(xiàn)DAO , Room 將在編譯時(shí)創(chuàng)建這個(gè) DAO 的實(shí)現(xiàn)。
需要注意的是,Room 不支持在主線程中訪問數(shù)據(jù)庫(kù),除非在構(gòu)建的時(shí)候調(diào)用了 allowMainThreadQueries() 方法。因?yàn)樵谒膶⑹欠浅:臅r(shí)的。

定義方法

你可以在 DAO 類中,使用很多方便的數(shù)據(jù)庫(kù)操作。

Insert

當(dāng)我們創(chuàng)建一個(gè)以 @Insert 注解的 DAO 方法的時(shí)候,Room 將在一個(gè)事務(wù)中產(chǎn)生一個(gè)插入它所有參數(shù)到數(shù)據(jù)庫(kù)實(shí)現(xiàn)

@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 方法僅僅接收一個(gè)參數(shù),它可以訪問一個(gè)long 類型數(shù)據(jù),代表了插入項(xiàng)的 rowId。以此類推,如果參數(shù)是一個(gè)數(shù)組或者集合,返回的將是 long [] 后者 List<Long>.

Update

Update 用以通過指定參數(shù)修改 entity 。
它首先會(huì)根據(jù) entity 的主鍵匹配數(shù)據(jù),然后修改對(duì)應(yīng)行的數(shù)據(jù)。

@Dao
public interface MyDao {
    @Update
    public void updateUsers(User... users);
}

當(dāng)然,你也可以讓這些方法返回一個(gè) int 值,代表更新的行號(hào)。

Delete

Delete 代表著從數(shù)據(jù)庫(kù)中刪除一系列的 entity(譯注:一個(gè)entity對(duì)應(yīng)著數(shù)據(jù)庫(kù)table中一個(gè)數(shù)據(jù)行)。它將使用主鍵找到那些需要被刪除的 entity。

@Dao
public interface MyDao {
    @Delete
    public void deleteUsers(User... users);
}
Query

@Query 是 DAO 類中的主要注解。它允許在數(shù)據(jù)庫(kù)中執(zhí)行讀寫操作。
查詢操作在編譯的時(shí)候就已經(jīng)確定了,如果這個(gè)查詢是有問題的,將會(huì)發(fā)生編譯錯(cuò)誤而不用等待運(yùn)行時(shí)報(bào)錯(cuò)。
Room 也檢查了查詢操作的返回值。如果返回對(duì)象的成員和相應(yīng)的 列 名不匹配,Room 將通過下面兩種方式給出警告:

  • 給出一個(gè)相關(guān)成員不匹配的的警告
  • 給出一個(gè) error
簡(jiǎn)單的查詢操作
@Dao
public interface MyDao {
    @Query("SELECT * FROM user")
    public User[] loadAllUsers();
}

上述是一個(gè)非常簡(jiǎn)單的查詢操作,將得到所有的 User 。在編譯的時(shí)候,Room 就知道它是查詢所有 user 表中的列,所以如果包含一些語法錯(cuò)誤,亦或者 user 并不存在,Room 顯示報(bào)錯(cuò)信息。

在查詢語句中添加參數(shù)

常常我們的查詢都是帶參數(shù)的,以進(jìn)行數(shù)據(jù)過濾,比如說只找到那些年齡大于某個(gè)數(shù)值的用戶。

@Dao
public interface MyDao {
    @Query("SELECT * FROM user WHERE age > :minAge")
    public User[] loadAllUsersOlderThan(int minAge);
}

在進(jìn)行編譯處理的時(shí)候,Room 會(huì)將方法中的 minAge 和 :minAge 進(jìn)行匹配設(shè)置。同樣,如果無法匹配(譯注:比如方法中不帶參數(shù),但是上面的查詢語句中卻帶有參數(shù)),就是顯示錯(cuò)誤信息。
當(dāng)然,你也可以傳遞多個(gè)參數(shù):

@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);
}

返回某些列

很多時(shí)候,我們只需要一個(gè) entity(一個(gè)數(shù)據(jù)行) 中的某些列。舉例而言,在 UI 中,你可能只需要展示用戶的姓和名,而不是關(guān)于用戶的所有信息。只查詢必要的信息,查詢完成的速度會(huì)更快。
Room 允許從查詢中返回一個(gè) Java 對(duì)象,只要這些列可以被映射為一個(gè)對(duì)象。舉例而言,你可以創(chuàng)建一個(gè)下面的 Java 對(duì)象僅僅獲取用戶的姓和名:

public class NameTuple {
    @ColumnInfo(name="first_name")
    public String firstName;

    @ColumnInfo(name="last_name")
    public String lastName;
}

現(xiàn)在,可以在查詢方法中返回這個(gè) POJO :

@Dao
public interface MyDao {
    @Query("SELECT first_name, last_name FROM user")
    public List<NameTuple> loadFullName();
}

Room 可以感知到返回的 first_name 和 last_name 列中的值可以被映射到 NameTuple 類中的屬性中。如果返回的太多列,或者返回的列中 NameTuple 類中并不存在這個(gè)屬性,Room 會(huì)給出警告。

傳遞一個(gè)集合參數(shù)

有些查詢操作可能需要傳遞的參數(shù)的個(gè)數(shù)是不確定的,只有在運(yùn)行的時(shí)候才知道具體的數(shù)量。舉個(gè)栗子,現(xiàn)在我們需要檢索出某幾個(gè)區(qū)域的用戶信息:

@Dao
public interface MyDao {
    @Query("SELECT first_name, last_name FROM user WHERE region IN (:regions)")
    public List<NameTuple> loadUsersFromRegions(List<String> regions);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容