Damit Abfragen die Benutzeroberfläche nicht blockieren, erlaubt Room keinen Datenbankzugriff auf den Hauptthread. Diese Einschränkung bedeutet, dass Sie Ihre DAO-Abfragen asynchron ausführen müssen. Die Room-Bibliothek bietet Integrationen mit mehreren verschiedenen Frameworks für die asynchrone Abfrageausführung.
DAO-Abfragen lassen sich in drei Kategorien unterteilen:
- Einmal schreiben-Abfragen, die Daten in die Datenbank einfügen, aktualisieren oder löschen.
- Einmalleseabfragen, bei denen Daten nur einmal aus der Datenbank gelesen und ein Ergebnis mit dem Snapshot der Datenbank zu diesem Zeitpunkt zurückgegeben werden.
- Beobachtbare Leseabfragen, bei denen jedes Mal, wenn sich die zugrunde liegenden Datenbanktabellen ändern, Daten aus Ihrer Datenbank gelesen und neue Werte ausgegeben werden, um diese Änderungen widerzuspiegeln.
Sprach- und Frameworkoptionen
Room bietet Integrationsunterstützung für die Interoperabilität mit bestimmten Sprachfunktionen und ‑bibliotheken. In der folgenden Tabelle sind die zulässigen Rückgabetypen nach Abfragetyp und Framework aufgeführt:
Abfragetyp | Kotlin-Sprachfunktionen | RxJava | Guava | Jetpack Lifecycle |
---|---|---|---|---|
Einmaliger Schreibvorgang | Coroutinen (suspend ) |
Single<T> , Maybe<T> ,
Completable |
ListenableFuture<T> |
– |
Einmaliges Lesen | Coroutinen (suspend ) |
Single<T> , Maybe<T> |
ListenableFuture<T> |
– |
Observable read | Flow<T> |
Flowable<T> , Publisher<T> ,
Observable<T> |
– | LiveData<T> |
In diesem Leitfaden werden drei Möglichkeiten beschrieben, wie Sie diese Integrationen verwenden können, um asynchrone Abfragen in Ihren DAOs zu implementieren.
Kotlin mit Flow und Coroutines
Kotlin bietet Sprachfunktionen, mit denen Sie asynchrone Abfragen ohne Frameworks von Drittanbietern schreiben können:
- In Room 2.2 und höher können Sie die Flow-Funktion von Kotlin verwenden, um beobachtbare Abfragen zu schreiben.
- In Room 2.1 und höher können Sie das Keyword
suspend
verwenden, um Ihre DAO-Abfragen mithilfe von Kotlin-Coroutines asynchron auszuführen.
Java mit RxJava
Wenn Sie in Ihrer App die Programmiersprache Java verwenden, können Sie spezielle Rückgabetypen aus dem RxJava-Framework verwenden, um asynchrone DAO-Methoden zu schreiben. Room unterstützt die folgenden RxJava 2-Rückgabetypen:
- Für einmalige Abfragen werden in Room 2.1 und höher die Rückgabetypen
Completable
,Single<T>
undMaybe<T>
unterstützt. - Für beobachtbare Abfragen unterstützt Room die Rückgabetypen
Publisher<T>
,Flowable<T>
undObservable<T>
.
Außerdem unterstützt Room 2.3 und höher RxJava 3.
Java mit LiveData und Guava
Wenn Sie in Ihrer App die Programmiersprache Java verwenden und das RxJava-Framework nicht verwenden möchten, können Sie asynchrone Abfragen mit den folgenden Alternativen schreiben:
- Sie können die Wrapper-Klasse
LiveData
von Jetpack verwenden, um asynchrone observable Abfragen zu schreiben. - Sie können den
ListenableFuture<T>
-Wrapper von Guava verwenden, um asynchrone Einmalabfragen zu schreiben.
Asynchrone Einmalabfragen schreiben
Einmalige Abfragen sind Datenbankvorgänge, die nur einmal ausgeführt werden und zum Zeitpunkt der Ausführung einen Snapshot der Daten erfassen. Hier einige Beispiele für asynchrone Einmalabfragen:
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); }
Beobachtbare Abfragen schreiben
Beobachtbare Abfragen sind Lesevorgänge, die neue Werte ausgeben, wenn sich eine der Tabellen ändert, auf die in der Abfrage verwiesen wird. So können Sie beispielsweise eine angezeigte Artikelliste auf dem neuesten Stand halten, wenn Artikel in der zugrunde liegenden Datenbank eingefügt, aktualisiert oder entfernt werden. Hier einige Beispiele für beobachtbare Abfragen:
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); }
Weitere Informationen
Weitere Informationen zu asynchronen DAO-Abfragen finden Sie in den folgenden zusätzlichen Ressourcen: