Untuk mencegah kueri memblokir UI, Room tidak mengizinkan akses database pada thread utama. Batasan ini berarti Anda harus membuat kueri DAO secara asinkron. Library Room menyertakan integrasi dengan beberapa framework berbeda untuk menyediakan eksekusi kueri asinkron.
Kueri DAO dibagi menjadi tiga kategori:
- Kueri tindakan tulis satu kali yang menyisipkan, memperbarui, atau menghapus data dalam database.
- Kueri tindakan baca satu kali yang membaca data dari database Anda hanya sekali dan menampilkan hasil beserta rekaman data dari database pada saat itu.
- Kueri tindakan baca yang dapat diamati yang membaca data dari database Anda setiap kali tabel database pokok berubah dan memunculkan nilai baru untuk mencerminkan perubahan tersebut.
Opsi bahasa dan framework
Room memberikan dukungan integrasi untuk interoperabilitas dengan library dan fitur bahasa tertentu. Tabel berikut menampilkan jenis nilai yang ditampilkan, yang dapat diterapkan berdasarkan jenis kueri dan framework:
Jenis kueri | Fitur bahasa Kotlin | RxJava | Guava | Siklus Proses Jetpack |
---|---|---|---|---|
Tindakan tulis satu kali | Coroutine (suspend ) |
Single<T> , Maybe<T> ,
Completable |
ListenableFuture<T> |
T/A |
Tindakan baca satu kali | Coroutine (suspend ) |
Single<T> , Maybe<T> |
ListenableFuture<T> |
T/A |
Tindakan baca yang dapat diamati | Flow<T> |
Flowable<T> , Publisher<T> ,
Observable<T> |
T/A | LiveData<T> |
Panduan ini menunjukkan tiga kemungkinan cara menggunakan integrasi tersebut untuk mengimplementasikan kueri asinkron di DAO.
Kotlin dengan Flow dan couroutine
Kotlin menyediakan fitur bahasa yang memungkinkan Anda menulis kueri asinkron tanpa framework pihak ketiga:
- Di Room 2.2 dan yang lebih tinggi, Anda dapat menggunakan fungsi Flow Kotlin untuk menulis kueri tindakan yang dapat diamati.
- Di Room 2.1 dan lebih tinggi, Anda dapat menggunakan kata kunci
suspend
untuk membuat kueri DAO menjadi asinkron menggunakan coroutine Kotlin.
Java dengan RxJava
Jika aplikasi menggunakan bahasa pemrograman Java, Anda dapat menggunakan jenis nilai yang ditampilkan khusus dari framework RxJava untuk menulis metode DAO asinkron. Room memberikan dukungan untuk jenis nilai yang ditampilkan RxJava 2 berikut:
- Untuk kueri tindakan satu kali, Room 2.1 dan yang lebih tinggi mendukung
jenis nilai yang ditampilkan
Completable
,Single<T>
, danMaybe<T>
. - Untuk kueri tindakan yang dapat diamati, Room mendukung
jenis nilai yang ditampilkan
Publisher<T>
,Flowable<T>
, danObservable<T>
.
Selain itu, Room 2.3 dan yang lebih tinggi juga mendukung RxJava 3.
Java dengan LiveData dan Guava
Jika aplikasi menggunakan bahasa pemrograman Java dan Anda tidak ingin menggunakan framework RxJava, Anda dapat menggunakan alternatif berikut untuk menulis kueri asinkron:
- Anda dapat menggunakan class wrapper
LiveData
dari Jetpack untuk menulis kueri asinkron tindakan yang dapat diamati. - Anda dapat menggunakan wrapper
ListenableFuture<T>
dari Guava untuk menulis kueri tindakan satu kali asinkron.
Menulis kueri satu kali asinkron
Kueri tindakan satu kali adalah operasi database yang hanya berjalan sekali dan mengambil rekaman data pada saat eksekusi. Berikut beberapa contoh kueri satu kali asinkron:
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); }
Menulis kueri yang dapat diamati
Kueri yang dapat diamati adalah operasi baca yang memunculkan nilai baru setiap kali ada perubahan pada tabel yang dirujuk oleh kueri. Salah satu manfaatnya adalah untuk membantu terus memperbarui daftar item yang ditampilkan saat item dalam database pokok disisipkan, diperbarui, atau dihapus. Berikut beberapa contoh kueri yang dapat diamati:
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); }
Referensi lainnya
Untuk mempelajari kueri DAO asinkron lebih lanjut, lihat referensi tambahan berikut: