Speichern Sie Daten in einer lokalen Datenbank mit Room Teil von Android Jetpack.
Anwendungen, die komplexe Mengen strukturierter Daten verarbeiten, können enorm davon profitieren, diese Daten lokal zu speichern. Am häufigsten werden relevante Daten im Cache gespeichert. Wenn das Gerät nicht auf das Netzwerk zugreifen kann, kann der Nutzer diese Inhalte auch dann durchsuchen, wenn er offline ist.
Die Room-Persistence-Bibliothek bietet eine Abstraktionsebene über SQLite, um einen fließenden Zugriff auf die Datenbank zu ermöglichen und gleichzeitig die volle Leistung von SQLite zu nutzen. Room bietet insbesondere folgende Vorteile:
- Verifizierung während der Kompilierung von SQL-Abfragen.
- Praktische Anmerkungen, die sich wiederholenden und fehleranfälligen Boilerplate-Code minimieren.
- Optimierte Datenbankmigrationspfade.
Aufgrund dieser Überlegungen empfehlen wir dringend, den Raum zu verwenden, anstatt die SQLite APIs direkt zu nutzen.
Einrichten
Wenn Sie Room in Ihrer Anwendung verwenden möchten, fügen Sie der Datei build.gradle
der Anwendung die folgenden Abhängigkeiten hinzu:
Cool
dependencies { def room_version = "2.6.1" implementation "androidx.room:room-runtime:$room_version" annotationProcessor "androidx.room:room-compiler:$room_version" // To use Kotlin annotation processing tool (kapt) kapt "androidx.room:room-compiler:$room_version" // To use Kotlin Symbol Processing (KSP) ksp "androidx.room:room-compiler:$room_version" // optional - RxJava2 support for Room implementation "androidx.room:room-rxjava2:$room_version" // optional - RxJava3 support for Room implementation "androidx.room:room-rxjava3:$room_version" // optional - Guava support for Room, including Optional and ListenableFuture implementation "androidx.room:room-guava:$room_version" // optional - Test helpers testImplementation "androidx.room:room-testing:$room_version" // optional - Paging 3 Integration implementation "androidx.room:room-paging:$room_version" }
Kotlin
dependencies { val room_version = "2.6.1" implementation("androidx.room:room-runtime:$room_version") annotationProcessor("androidx.room:room-compiler:$room_version") // To use Kotlin annotation processing tool (kapt) kapt("androidx.room:room-compiler:$room_version") // To use Kotlin Symbol Processing (KSP) ksp("androidx.room:room-compiler:$room_version") // optional - Kotlin Extensions and Coroutines support for Room implementation("androidx.room:room-ktx:$room_version") // optional - RxJava2 support for Room implementation("androidx.room:room-rxjava2:$room_version") // optional - RxJava3 support for Room implementation("androidx.room:room-rxjava3:$room_version") // optional - Guava support for Room, including Optional and ListenableFuture implementation("androidx.room:room-guava:$room_version") // optional - Test helpers testImplementation("androidx.room:room-testing:$room_version") // optional - Paging 3 Integration implementation("androidx.room:room-paging:$room_version") }
Hauptkomponenten
In Room gibt es drei Hauptkomponenten:
- Die Datenbankklasse mit der Datenbank und Hauptzugriffspunkt für die zugrunde liegende Verbindung zu den persistenten Daten Ihrer Anwendung.
- Datenentitäten, die Tabellen in der Datenbank Ihrer Anwendung darstellen
- Datenzugriffsobjekte (Data Access Objects, DAOs), die Methoden bereitstellen, mit denen Ihre Anwendung Daten in der Datenbank abfragen, aktualisieren, einfügen und löschen kann.
Die Datenbankklasse stellt Ihrer Anwendung Instanzen der DAOs bereit, die mit dieser Datenbank verknüpft sind. Die Anwendung kann wiederum die DAOs verwenden, um Daten aus der Datenbank als Instanzen der verknüpften Datenentitätsobjekte abzurufen. Die Anwendung kann die definierten Datenentitäten auch verwenden, um Zeilen aus den entsprechenden Tabellen zu aktualisieren oder neue Zeilen für das Einfügen zu erstellen. In Abbildung 1 sehen Sie die Beziehung zwischen den verschiedenen Raumkomponenten.
Implementierungsbeispiel
In diesem Abschnitt wird eine Beispielimplementierung einer Raumdatenbank mit einer einzelnen Datenentität und einem einzelnen DAO vorgestellt.
Datenentität
Mit dem folgenden Code wird eine User
-Datenentität definiert. Jede Instanz von User
stellt eine Zeile in einer user
-Tabelle in der Datenbank der Anwendung dar.
Kotlin
@Entity data class User( @PrimaryKey val uid: Int, @ColumnInfo(name = "first_name") val firstName: String?, @ColumnInfo(name = "last_name") val lastName: String? )
Java
@Entity public class User { @PrimaryKey public int uid; @ColumnInfo(name = "first_name") public String firstName; @ColumnInfo(name = "last_name") public String lastName; }
Weitere Informationen zu Datenentitäten in Room finden Sie unter Daten mithilfe von Room-Entitäten definieren.
Datenzugriffsobjekt (DAO)
Mit dem folgenden Code wird ein DAO mit dem Namen UserDao
definiert. UserDao
stellt die Methoden bereit, die der Rest der Anwendung für die Interaktion mit Daten in der Tabelle user
verwendet.
Kotlin
@Dao interface UserDao { @Query("SELECT * FROM user") fun getAll(): List<User> @Query("SELECT * FROM user WHERE uid IN (:userIds)") fun loadAllByIds(userIds: IntArray): List<User> @Query("SELECT * FROM user WHERE first_name LIKE :first AND " "last_name LIKE :last LIMIT 1") fun findByName(first: String, last: String): User @Insert fun insertAll(vararg users: User) @Delete fun delete(user: User) }
Java
@Dao public interface UserDao { @Query("SELECT * FROM user") List<User> getAll(); @Query("SELECT * FROM user WHERE uid IN (:userIds)") List<User> loadAllByIds(int[] userIds); @Query("SELECT * FROM user WHERE first_name LIKE :first AND " "last_name LIKE :last LIMIT 1") User findByName(String first, String last); @Insert void insertAll(User... users); @Delete void delete(User user); }
Weitere Informationen zu DAOs finden Sie unter Mit Raum-DAOs auf Daten zugreifen.
Datenbank
Mit dem folgenden Code wird eine AppDatabase
-Klasse für die Datenbank definiert.
AppDatabase
definiert die Datenbankkonfiguration und dient als Hauptzugriffspunkt der Anwendung auf die gespeicherten Daten. Die Datenbankklasse muss die folgenden Bedingungen erfüllen:
- Die Klasse muss mit einer
@Database
-Annotation annotiert werden, die einentities
-Array enthält, in dem alle mit der Datenbank verknüpften Datenentitäten aufgelistet sind. - Die Klasse muss eine abstrakte Klasse sein, die
RoomDatabase
erweitert. - Für jede mit der Datenbank verknüpfte DAO-Klasse muss die Datenbankklasse eine abstrakte Methode definieren, die keine Argumente hat und eine Instanz der DAO-Klasse zurückgibt.
Kotlin
@Database(entities = [User::class], version = 1) abstract class AppDatabase : RoomDatabase() { abstract fun userDao(): UserDao }
Java
@Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
Hinweis : Wenn Ihre Anwendung in einem einzigen Prozess ausgeführt wird, sollten Sie beim Instanziieren eines AppDatabase
-Objekts dem Singleton-Designmuster folgen. Jede RoomDatabase
-Instanz ist relativ teuer und Sie benötigen selten Zugriff auf mehrere Instanzen innerhalb eines einzelnen Prozesses.
Wenn Ihre Anwendung in mehreren Prozessen ausgeführt wird, fügen Sie enableMultiInstanceInvalidation()
in den Aufruf des Database Builder ein. Wenn also in jedem Prozess eine Instanz von AppDatabase
vorhanden ist, können Sie die freigegebene Datenbankdatei in einem Prozess entwerten. Diese Entwertung wird dann automatisch an die Instanzen von AppDatabase
in anderen Prozessen weitergegeben.
Nutzung
Nachdem Sie die Datenentität, die DAO und das Datenbankobjekt definiert haben, können Sie mit dem folgenden Code eine Instanz der Datenbank erstellen:
Kotlin
val db = Room.databaseBuilder( applicationContext, AppDatabase::class.java, "database-name" ).build()
Java
AppDatabase db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "database-name").build();
Sie können dann die abstrakten Methoden aus dem AppDatabase
verwenden, um eine Instanz der DAO abzurufen. Sie können wiederum die Methoden der DAO-Instanz verwenden, um mit der Datenbank zu interagieren:
Kotlin
val userDao = db.userDao() val users: List<User> = userDao.getAll()
Java
UserDao userDao = db.userDao(); List<User> users = userDao.getAll();
Weitere Informationen
Weitere Informationen zu Room finden Sie in den folgenden Ressourcen: