美文网首页
Jetpack 详解之 Room 二 DAO类详解

Jetpack 详解之 Room 二 DAO类详解

作者: Kael_Zhang的安卓笔记 | 来源:发表于2022-09-27 11:00 被阅读0次

引言

当您使用 Room 持久性库存储应用的数据时,您可以通过定义数据访问对象 (DAO) 与存储的数据进行交互。每个 DAO 都包含一些方法,这些方法提供对应用数据库的抽象访问权限。在编译时,Room 会自动为您定义的 DAO 生成实现

DAO 剖析

您可以将每个 DAO 定义为一个接口或一个抽象类。
对于基本用例,您通常应使用接口。无论是哪种情况,您都必须始终使用 @Dao为您的 DAO 添加注解。
DAO 不具有属性,但它们定义了一个或多个方法,可用于与应用数据库中的数据进行交互。
以下代码是一个简单 DAO 的示例,它定义了在 Room 数据库中插入、删除和选择 User 对象的方法:

@Dao
interface UserDao {
    @Insert
    fun insertAll(vararg users: User)

    @Delete
    fun delete(user: User)

    @Query("SELECT * FROM user")
    fun getAll(): List<User>
}

有两种类型的 DAO 方法可以定义数据库交互:

  • (便捷方法)可让您在不编写任何 SQL 代码的情况下插入、更新和删除数据库中行的便捷方法。
  • (传统SQL语句方法)可让您编写自己的 SQL 查询以与数据库进行交互的查询方法。

便捷方法

Room 提供了方便的注解,用于定义无需编写 SQL 语句即可执行简单插入、更新和删除的方法

  • 插入

借助 @Insert注释,您可以定义将其参数插入到数据库中的相应表中的方法。
@Insert 方法的每个参数必须是带有 @Entity 注解的 Room 数据实体类的实例或数据实体类实例的集合。调用 @Insert 方法时,Room 会将每个传递的实体实例插入到相应的数据库表中。
如果 @Insert 方法接收单个参数,则会返回 long 值,这是插入项的新 rowId。如果参数是数组或集合,则该方法应改为返回由 long 值组成的数组或集合,并且每个值都作为其中一个插入项的 rowId
以下代码展示了将一个或多个 User 对象插入数据库的有效 @Insert 方法示例:

@Dao
interface UserDao {

    //OnConflictStrategy.REPLACE:如果有老的数据存在则会进行替换,如果没有就插入
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertUsers(vararg users: User)

    @Insert
    fun insertBothUsers(user1: User, user2: User)

    @Insert
    fun insertUsersAndFriends(user: User, friends: List<User>)
}
  • 更新

借助 @Update注释,您可以定义更新数据库表中特定行的方法。与 @Insert 方法类似,@Update 方法接受数据实体实例作为参数。 以下代码展示了一个 @Update 方法示例,该方法尝试更新数据库中的一个或多个 User 对象(匹配主键更新),@Update 方法可以选择性地返回 int 值,该值指示成功更新的行数

@Dao
interface UserDao {
    @Update
    fun updateUsers(vararg users: User)
}
  • 删除

借助 @Delete注释,您可以定义从数据库表中删除特定行的方法。与 @Insert 方法类似,@Delete 方法接受数据实体实例作为参数。 以下代码展示了一个 @Delete 方法示例,尝试从数据库中删除一个或多个 User 对象(匹配主键删除),@Delete方法可以选择性地返回 int 值,该值指示成功删除的行数

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

传统SQL语句方法

使用 @Query注解,您可以编写 SQL 语句并将其作为 DAO 方法公开。使用这些查询方法从应用的数据库查询数据,或者需要执行更复杂的插入、更新和删除操作。
Room 会在编译时验证 SQL 查询。这意味着,如果查询出现问题,则会出现编译错误,而不是运行时失败

  • 查询,查询表中所有数据
@Query("SELECT * FROM user")
fun loadAllUsers(): Array<User>
  • 查询,返回表格列的子集(另外创建一个新类,只查询数据中的姓名数据,不查询其他数据,节省资源)
    在大多数情况下,您只需要返回要查询的表中的列的子集。例如,您的界面可能仅显示用户的名字和姓氏,而不是该用户的每一条详细信息。为节省资源并简化查询的执行,您应只查询所需的字段。
    借助 Room,您可以从任何查询返回简单对象,前提是您可以将一组结果列映射到返回的对象。例如,您可以定义以下对象来保存用户的名字和姓氏:
data class NameTuple(
    @ColumnInfo(name = "first_name") val firstName: String?,
    @ColumnInfo(name = "last_name") val lastName: String?
)
@Query("SELECT first_name, last_name FROM user")
fun loadFullName(): List<NameTuple>
  • 查询,将简单参数传递给查询

年龄区间查询

@Query("SELECT * FROM user WHERE age > :minAge")
fun loadAllUsersOlderThan(minAge: Int): Array<User>

@Query("SELECT * FROM user WHERE age BETWEEN :minAge AND :maxAge")
fun loadAllUsersBetweenAges(minAge: Int, maxAge: Int): Array<User>
  • 查询,将一组参数传递给查询
@Query("SELECT * FROM user WHERE region IN (:regions)")
fun loadUsersFromRegions(regions: List<String>): List<User>
  • 查询,多表联合查询
@Query(
    "SELECT * FROM book " +
    "INNER JOIN loan ON loan.book_id = book.id " +
    "INNER JOIN user ON user.id = loan.user_id " +
    "WHERE user.name LIKE :userName"
)
fun findBooksBorrowedByNameSync(userName: String): List<Book>

相关文章

网友评论

      本文标题:Jetpack 详解之 Room 二 DAO类详解

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