Aby zapobiec blokowaniu interfejsu przez zapytania, pokój nie zezwala na dostęp do bazy danych w wątku głównym. Ograniczenie to oznacza, że zapytania związane z DAO muszą być asynchroniczne. Biblioteka sal zawiera integracje z kilkoma różnymi platformami, które pozwalają na asynchroniczne wykonywanie zapytań.
Zapytania dotyczące DAO można podzielić na 3 kategorie:
- Zapytania jednorazowe zapisu służące do wstawiania, aktualizowania i usuwania danych w bazie danych.
- Zapytania odczytu jednorazowego, które odczytują dane z bazy danych tylko raz i zwracają wynik ze zrzutem bazy danych w danym momencie.
- Zapytania dostrzegalne do odczytu, które odczytują dane z bazy danych po każdej zmianie jej tabel i generują nowe wartości, które odzwierciedlają te zmiany.
Opcje języka i platformy
Room zapewnia możliwość integracji w celu interoperacyjności z określonymi funkcjami i bibliotekami językowymi. W tej tabeli znajdziesz odpowiednie typy zwracanych na podstawie typu zapytania i platformy:
Typ zapytania | Funkcje języka Kotlin | RxJava | Gujawa | Cykl życia plecaka Jetpack |
---|---|---|---|---|
Zapis jednorazowy | Korutyny (suspend ) |
Single<T> , Maybe<T> ,
Completable |
ListenableFuture<T> |
Nie dotyczy |
Czytanie jednym ujęciem | Korutyny (suspend ) |
Single<T> , Maybe<T> |
ListenableFuture<T> |
Nie dotyczy |
Dostrzegalny odczyt | Flow<T> |
Flowable<T> , Publisher<T> ,
Observable<T> |
Nie dotyczy | LiveData<T> |
W tym przewodniku omawiamy 3 możliwe sposoby wykorzystania tych integracji do implementacji zapytań asynchronicznych w DAO.
Kotlin z Flow i couroutines
Kotlin udostępnia funkcje językowe, które umożliwiają pisanie asynchronicznych zapytań bez platform innych firm:
- W pokoju 2.2 i nowszych możesz tworzyć obserwowalne zapytania Kotlin, korzystając z funkcji Flow.
- W pokoju 2.1 i nowszych możesz użyć słowa kluczowego
suspend
, aby asynchronicznie wykonywać zapytania DAO za pomocą kotlinów.
Java i RxJava
Jeśli Twoja aplikacja używa języka programowania Java, do zapisywania asynchronicznych metod DAO możesz używać specjalistycznych typów zwrotów z platformy RxJava. Room zapewnia obsługę następujących typów zwrotów RxJava 2:
- W przypadku zapytań jednorazowych pokoje 2.1 i nowsze obsługują typy zwrotów
Completable
,Single<T>
iMaybe<T>
. - W przypadku zapytań dostępnych do obserwacji pokój obsługuje typy zwrotów
Publisher<T>
,Flowable<T>
iObservable<T>
.
Ponadto Room 2.3 i nowsze wersje obsługują język RxJava 3.
Java z LiveData i Gujawą
Jeśli Twoja aplikacja używa języka programowania Java i nie chcesz korzystać z platformy RxJava, możesz zapisywać zapytania asynchroniczne, korzystając z tych alternatywnych rozwiązań:
- Do pisania asynchronicznych obserwowalnych zapytań możesz używać klasy otoki
LiveData
z Jetpack. - Do pisania asynchronicznych zapytań typu „one-shot” możesz używać otoki
ListenableFuture<T>
z Gujawy.
Tworzenie asynchronicznych zapytań typu „one-shot”
Zapytania jednorazowe to operacje na bazie danych, które są wykonywane tylko raz i rejestrują zrzut danych w momencie wykonywania. Oto kilka przykładów asynchronicznego zapytania „one-shot”:
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); }
Utwórz obserwowalne zapytania
Dostrzegalne zapytania to operacje odczytu, które generują nowe wartości, gdy nastąpi zmiana w którejkolwiek z tabel, do których odwołuje się zapytanie. Możesz na przykład korzystać z tej opcji, aby aktualizować wyświetlaną listę elementów w miarę ich wstawiania, aktualizowania lub usuwania. Oto kilka przykładów zapytań dostępnych do obserwacji:
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); }
Dodatkowe materiały
Więcej informacji o asynchronicznych zapytaniach DAO znajdziesz w tych materiałach dodatkowych: