เขียนคำค้นหา DAO แบบไม่พร้อมกัน

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 แบบไม่พร้อมกัน โปรดดูข้อมูลต่อไปนี้ แหล่งข้อมูล:

ตัวอย่าง

  • ห้องและ ตัวอย่าง RxJava (Java) (Kotlin)

บล็อก