Zapisz asynchroniczne zapytania DAO

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:

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:

Próbki

Blogi