Room ไม่อนุญาตให้เข้าถึงฐานข้อมูลในเธรดหลักเพื่อป้องกันไม่ให้การค้นหาบล็อก UI ข้อจำกัดนี้หมายความว่าคุณต้องทำให้ DAO ของคุณ แบบไม่พร้อมกัน ห้องสมุด Room มีการผสานรวมกับเฟรมเวิร์กต่างๆ เพื่อดำเนินการค้นหาแบบไม่พร้อมกัน
การค้นหา DAO แบ่งออกเป็น 3 หมวดหมู่ ดังนี้
- การค้นหาการเขียนแบบ One-shot ที่จะแทรก อัปเดต หรือลบข้อมูลในฐานข้อมูล
- การค้นหาการอ่านแบบครั้งเดียวที่อ่านข้อมูลจากฐานข้อมูลของคุณเพียงครั้งเดียวและส่งกลับ ผลลัพธ์พร้อมกับภาพรวมของฐานข้อมูลในเวลานั้น
- การค้นหาที่อ่านแล้วที่สังเกตได้ซึ่งอ่านข้อมูลจากฐานข้อมูลของคุณทุกครั้ง ตารางฐานข้อมูลที่สําคัญจะเปลี่ยนแปลงและระบุค่าใหม่เพื่อแสดงถึงตารางเหล่านั้น การเปลี่ยนแปลง
ตัวเลือกภาษาและเฟรมเวิร์ก
ห้องแชทมีการสนับสนุนการผสานรวมเพื่อการทำงานร่วมกันกับภาษาที่ระบุ ฟีเจอร์ต่างๆ และไลบรารี ตารางต่อไปนี้แสดงประเภทผลตอบแทนที่เกี่ยวข้องตาม เกี่ยวกับประเภทและกรอบของข้อความค้นหา:
ประเภทคำค้นหา | ฟีเจอร์ภาษา Kotlin | อาร์กจาวา | ชมพูกวาวา | วงจรการใช้งาน Jetpack |
---|---|---|---|---|
การเขียนแบบ One-shot | โครูทีน (suspend ) |
Single<T> Maybe<T>
Completable |
ListenableFuture<T> |
ไม่มี |
การอ่านแบบครั้งเดียว | โครูทีน (suspend ) |
Single<T> , Maybe<T> |
ListenableFuture<T> |
ไม่มี |
การอ่านที่สังเกตได้ | Flow<T> |
Flowable<T> Publisher<T>
Observable<T> |
ไม่มี | LiveData<T> |
คู่มือนี้แสดงวิธี 3 วิธีที่คุณสามารถใช้การผสานรวมเหล่านี้เพื่อใช้การค้นหาแบบไม่พร้อมกันใน DAO
Kotlin กับ Flow และ couroutines
Kotlin มีฟีเจอร์ด้านภาษาที่ให้คุณเขียนคำค้นหาแบบไม่พร้อมกัน ที่ไม่มีเฟรมเวิร์กของบุคคลที่สาม
- ในห้อง 2.2 ขึ้นไป คุณสามารถใช้ Kotlin โฟลว์ ในการเขียนการค้นหาที่สังเกตได้
- ในห้อง 2.1 ขึ้นไป คุณสามารถใช้คีย์เวิร์ด
suspend
เพื่อทำให้ DAO ของคุณ การค้นหาแบบไม่พร้อมกันโดยใช้ Kotlin coroutines
Java กับ RxJava
หากแอปของคุณใช้ภาษาในการเขียนโปรแกรม Java คุณสามารถใช้การตอบกลับเฉพาะ จากเฟรมเวิร์ก RxJava เพื่อเขียนเมธอด DAO แบบไม่พร้อมกัน ห้องพักมี การรองรับการแสดงผล RxJava 2 ประเภทต่อไปนี้
- สำหรับการค้นหาแบบครั้งเดียว ห้อง 2.1 ขึ้นไปจะสนับสนุน
Completable
Single<T>
และMaybe<T>
ประเภทการแสดงผล - สำหรับการค้นหาที่สังเกตได้ Room รองรับฟังก์ชัน
Publisher<T>
Flowable<T>
และObservable<T>
ประเภทการแสดงผล
นอกจากนี้ ห้อง 2.3 ขึ้นไปยังรองรับ RxJava 3 ด้วย
Java กับ LiveData และ Guava
หากแอปของคุณใช้ภาษาในการเขียนโปรแกรม Java และคุณไม่ต้องการใช้ เฟรมเวิร์ก RxJava คุณสามารถใช้ทางเลือกต่อไปนี้เพื่อเขียนแบบอะซิงโครนัสได้ ข้อความค้นหา:
- คุณจะใช้ Wrapper ของ
LiveData
ได้ จาก Jetpack ให้เขียนข้อความค้นหาที่สังเกตได้แบบไม่พร้อมกัน - คุณสามารถใช้
ListenableFuture<T>
Wrapper จาก Guava เพื่อเขียนคำค้นหาแบบครั้งเดียวแบบอะซิงโครนัส
เขียนการค้นหาแบบครั้งเดียวแบบอะซิงโครนัส
การค้นหาแบบครั้งเดียวคือการดำเนินการฐานข้อมูลที่เรียกใช้เพียงครั้งเดียวและเก็บสแนปชอต ข้อมูลมากขึ้นขณะดำเนินการ ต่อไปนี้เป็นตัวอย่างบางส่วนของแบบอะซิงโครนัส ข้อความค้นหาแบบครั้งเดียว:
Kotlin
@Dao interface UserDao { @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertUsers(vararg users: User) @Update suspend fun updateUsers(vararg users: User) @Delete suspend fun deleteUsers(vararg users: User) @Query("SELECT * FROM user WHERE id = :id") suspend fun loadUserById(id: Int): User @Query("SELECT * from user WHERE region IN (:regions)") suspend fun loadUsersByRegion(regions: List<String>): List<User> }
Java
@Dao public interface UserDao { @Insert(onConflict = OnConflictStrategy.REPLACE) public Completable insertUsers(List<User> users); @Update public Completable updateUsers(List<User> users); @Delete public Completable deleteUsers(List<User> users); @Query("SELECT * FROM user WHERE id = :id") public Single<User> loadUserById(int id); @Query("SELECT * from user WHERE region IN (:regions)") public Single<List<User>> loadUsersByRegion(List<String> regions); }
Java
@Dao public interface UserDao { // Returns the number of users inserted. @Insert(onConflict = OnConflictStrategy.REPLACE) public ListenableFuture<Integer> insertUsers(List<User> users); // Returns the number of users updated. @Update public ListenableFuture<Integer> updateUsers(List<User> users); // Returns the number of users deleted. @Delete public ListenableFuture<Integer> deleteUsers(List<User> users); @Query("SELECT * FROM user WHERE id = :id") public ListenableFuture<User> loadUserById(int id); @Query("SELECT * from user WHERE region IN (:regions)") public ListenableFuture<List<User>> loadUsersByRegion(List<String> regions); }
เขียนการค้นหาที่สังเกตได้
การค้นหาที่สังเกตได้คือการดำเนินการอ่านที่แสดงค่าใหม่เมื่อใดก็ตามที่มี การเปลี่ยนแปลงในตารางใดก็ตามที่อ้างอิงโดยการค้นหา วิธีหนึ่งที่คุณอาจ ใช้เพื่อช่วยให้คุณแสดงรายการสินค้าที่แสดงอยู่อยู่เสมอเป็นรายการล่าสุด ในฐานข้อมูลที่สำคัญจะถูกแทรก อัปเดต หรือนำออก ตัวอย่างการค้นหาที่สังเกตได้มีดังนี้
Kotlin
@Dao interface UserDao { @Query("SELECT * FROM user WHERE id = :id") fun loadUserById(id: Int): Flow<User> @Query("SELECT * from user WHERE region IN (:regions)") fun loadUsersByRegion(regions: List<String>): Flow<List<User>> }
Java
@Dao public interface UserDao { @Query("SELECT * FROM user WHERE id = :id") public Flowable<User> loadUserById(int id); @Query("SELECT * from user WHERE region IN (:regions)") public Flowable<List<User>> loadUsersByRegion(List<String> regions); }
Java
@Dao public interface UserDao { @Query("SELECT * FROM user WHERE id = :id") public LiveData<User> loadUserById(int id); @Query("SELECT * from user WHERE region IN (:regions)") public LiveData<List<User>> loadUsersByRegion(List<String> regions); }
แหล่งข้อมูลเพิ่มเติม
หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับคำสืบค้น DAO แบบไม่พร้อมกัน โปรดดูข้อมูลต่อไปนี้ แหล่งข้อมูล: