天天看點

Jetpack Room入門系列:(二)使用DAO讀寫資料庫@Insert 插入@Update 更新@Delete 删除@Query 查詢

Jetpack Room入門系列:(二)使用DAO讀寫資料庫@Insert 插入@Update 更新@Delete 删除@Query 查詢

Jetpack Room入門系列:(一)基本介紹

Jetpack Room入門系列:(二)使用DAO讀寫資料庫

Jetpack Room入門系列:(三)實體/資料表關系

Jetpack Room入門系列:(四)内部實作原理

Jetpack Room入門系列:(五)資料庫版本更新、資料遷移

Jetpack Room入門系列:(六)配合LiveData等三方庫的使用

Room中使用Data Access Objects( DAO)對資料庫進行讀寫,相對于SQL語句直接查詢,DAO可以定義更加友好的API。DAO中可以自定義CURD方法,還可以友善地與

RxJava

LiveData

等進行內建。

我們可以使用接口或者抽象類定一個DAO,如果使用抽象類,可以選擇性的為其定義構造函數,并接受Database作為唯一參數。

Room在編譯期會基于定義的DAO生成具體實作類,實作具體CURD方法。

@Insert 插入

@Insert

注解插入操作,編譯期生成的代碼會将所有的參數以單獨的事務更新到DB。

@Dao
interface UserDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertUsers(vararg users: User)   
    @Insert fun insertBothUsers(user1: User, user2: User)   
    @Insert fun insertUsersAndFriends(user: User, friends: List<User>)
}
           

onConflict

設定當事務中遇到沖突時的政策

  • OnConflictStrategy.REPLACE : 替換舊值,繼續目前事務
  • OnConflictStrategy.ROLLBACK : 復原目前事務
  • OnConflictStrategy.ABORT : 結束目前事務、復原
  • OnConflictStrategy.FAIL : 目前事務失敗、復原
  • OnConflictStrategy.NONE : 忽略沖突,繼續目前事務
最新代碼中ROLLBACK 和 FAIL 已經deprecated了,使用ABORT替代

@Update 更新

@Update注解定義更新操作,根據參數對象的主鍵更新指定row的資料

@Dao
interface UserDao {
    @Update(onConflict = OnConflictStrategy.REPLACE)
    fun updateUsers(vararg users: User)   
    @Update fun update(user: User)
}
           

@Delete 删除

@Delete定義删除操作,根據主鍵删除指定row

@Dao
interface UserDao {
    @Delete
    fun deleteUsers(vararg users: User)
}
           

@Query 查詢

@Query

注解定義查詢操作。@Query中的SQL語句以及傳回值類型等會在編譯期進行檢查,更早的暴露問題

@Dao
interface UserDao {
    @Query("SELECT * FROM users")
    fun loadAllUsers(): Array<User>
}
           

指定參數

可以用參數指定@Query中的where條件:

@Dao
interface UserDao {
    @Query("SELECT * FROM users WHERE age BETWEEN :minAge AND :maxAge")
    fun loadAllUsersBetweenAges(minAge: Int, maxAge: Int): Array<User>

    @Query("SELECT * FROM users WHERE first_name LIKE :search " +
           "OR last_name LIKE :search")
    fun findUserWithName(search: String): List<User>
}
           

傳回子集

傳回的結果可以是所有column的子集:

data class NameTuple(
    @ColumnInfo(name = "first_name") val firstName: String?,
    @ColumnInfo(name = "last_name") val lastName: String?
)@Dao
interface UserDao {
    @Query("SELECT first_name, last_name FROM users")
    fun loadFullName(): List<NameTuple>
}
           

傳回Cursor

傳回Cursor,可以基于Cursor進行進一步操作

@Dao
interface UserDao {
    @Query("SELECT * FROM users")
    fun loadAllUsers(): Cursor
}
           

多表查詢

@Dao
interface BookDao {
    @Query(
        "SELECT * FROM book " +
        "INNER JOIN loan ON loan.book_id = book.id " +
        "INNER JOIN user ON user.id = loan.user_id " +
        "WHERE users.name LIKE :userName"
    )
    fun findBooksBorrowedByNameSync(userName: String): List<Book>
}
           

SQL可以寫任何語句,包括多表連接配接等

傳回類型

Room可以傳回Coroutine、RxJava等多個常用庫的類型結果,便于在異步、響應式開發中使用

Jetpack Room入門系列:(二)使用DAO讀寫資料庫@Insert 插入@Update 更新@Delete 删除@Query 查詢