Android – 房间数据库中的数据访问对象
Room 中使用数据访问对象或 DAO 来访问应用程序的持久数据。与查询构建器或直接查询相比,它们是访问数据库的更好、更模块化的方式。您还应该注意,DAO 不必只是一个类。如果它是一个抽象类,它可以有一个只接受 RoomDatabase 作为参数的函数Object() { [native code] }。在编译时,Room 创建每个 DAO 实现。 DAO 允许您执行各种操作,例如插入、更新、删除和运行原始查询。您还可以轻松地将 LiveData、RxJava Observables 和 Kotlin Coroutines 合并到 DAO 中。
插入
当您使用 @Insert 注释 DAO 方法时,Room 会生成一个实现,该实现在单个事务中将所有参数插入数据库。
Kotlin
@Dao
interface gfgDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertCourses(vararg course: Course) @Insert
fun insertAndroid(course1: Course, course2: Course)
@Insert
fun insertDataStructures(course: Course, prices: List)
}
Kotlin
@Dao
interface CourseDAO {
@Update(onConflict = OnConflictStrategy.REPLACE)
fun updateCourses(vararg courses: Course)
@Update
fun update(courses: Course)
}
Kotlin
@Dao
interface CoursesDao {
@Delete
fun removeCourses(vararg courses: Courses)
}
Kotlin
@Dao
interface CoursesDao {
@Query("SELECT * FROM courses")
fun loadCourses(): Array
}
Kotlin
@Dao
interface CoursesDao {
@Query("SELECT * FROM courses WHERE price BETWEEN :minPrice AND :maxPrice")
fun loadAllCourses(minPrices: Int, maxPrices: Int): Array
@Query("SELECT * FROM courses WHERE first_course LIKE :search " +
"OR last_course LIKE :search")
fun findCourses(search: String): List
}
Kotlin
data class coursesTuple(
@CourseName(name = "first_course") val first_course: String?,
@CourseName(name = "last_course") val last_course: String?
)@Dao
interface courseDao {
@Query("SELECT first_name, last_name FROM course")
fun loadCourses(): List
}
Kotlin
@Dao
interface UserDAO {
@Query(
"SELECT * FROM users " +
"INNER JOIN loan ON loan.book_id = course.id " +
"INNER JOIN user ON user.id = loan.course " +
"WHERE course.name LIKE :courseName"
)
fun fingCourseTakenBy(courseName: String): List
}
onConflict注释参数指示在插入过程中发生冲突时应采取的措施。它可以是以下任何值:
- OnConflictStrategy.REPLACE :替换旧数据并继续事务。
- OnConflictStrategy.ROLLBACK :撤消事务。
- OnConflictStrategy.ABORT :取消交易。交易已撤销。
- OnConflictStrategy.FAIL:使事务失败。交易已撤销。
- OnConflictStrategy.NONE :忽略冲突。
Note: ROLLBACK and FAIL strategies are no longer supported. Instead, use ABORT.
科特林
@Dao
interface CourseDAO {
@Update(onConflict = OnConflictStrategy.REPLACE)
fun updateCourses(vararg courses: Course)
@Update
fun update(courses: Course)
}
删除
当您创建 DAO 方法并使用@Delete对其进行注释时,Room 会生成一个实现,该实现从数据库中删除一组由参数指定的实体。它使用主键搜索要删除的实体。
科特林
@Dao
interface CoursesDao {
@Delete
fun removeCourses(vararg courses: Courses)
}
简单的问题
DAO 类中使用的主要注解是@Query。它使您能够从数据库中读取和写入数据。因为每个@Query 方法都在编译时进行验证,所以如果查询出现问题,则会发生编译错误而不是运行时失败。 Room 还会验证查询的返回值,因此如果返回对象中的字段名称与查询响应中的相应列名称不匹配,Room 会通过以下两种方式之一通知您:字段名称匹配。如果没有匹配的字段名称,则返回错误。
科特林
@Dao
interface CoursesDao {
@Query("SELECT * FROM courses")
fun loadCourses(): Array
}
在查询中包含参数
传递给 DAO 方法的参数可以在使用 @Query 注释编写的查询中使用。
科特林
@Dao
interface CoursesDao {
@Query("SELECT * FROM courses WHERE price BETWEEN :minPrice AND :maxPrice")
fun loadAllCourses(minPrices: Int, maxPrices: Int): Array
@Query("SELECT * FROM courses WHERE first_course LIKE :search " +
"OR last_course LIKE :search")
fun findCourses(search: String): List
}
返回列子集
在室内,您还可以从查询中返回列的子集。
科特林
data class coursesTuple(
@CourseName(name = "first_course") val first_course: String?,
@CourseName(name = "last_course") val last_course: String?
)@Dao
interface courseDao {
@Query("SELECT first_name, last_name FROM course")
fun loadCourses(): List
}
多表查询
您的某些查询可能需要访问多个表才能计算结果。 Room 允许您编写任何查询,包括表连接。此外,如果响应是可观察的数据类型,例如 Flowable 或 LiveData,Room 会在查询中引用的所有表中查找失效。
科特林
@Dao
interface UserDAO {
@Query(
"SELECT * FROM users " +
"INNER JOIN loan ON loan.book_id = course.id " +
"INNER JOIN user ON user.id = loan.course " +
"WHERE course.name LIKE :courseName"
)
fun fingCourseTakenBy(courseName: String): List
}
查询返回的类型
该房间支持广泛的查询方法返回类型,包括用于与特定框架或 API 互操作的专用返回类型。查询方法可以返回 LiveData、Observable 和 Flow 对象。您还可以创建一个 DAO 方法的挂起函数。单独的文章专门针对这些主题中的每一个。