Daten mit Room in einer lokalen Datenbank speichern   Teil von Android Jetpack.

Mit Kotlin Multiplatform testen
Mit Kotlin Multiplatform kann die Datenbankebene mit anderen Plattformen geteilt werden. Informationen zum Einrichten und Verwenden von Room Database in KMP

Apps, die nicht unerhebliche Mengen strukturierter Daten verarbeiten, können von der lokalen Speicherung dieser Daten profitieren. Der häufigste Anwendungsfall ist das Speichern relevanter Daten im Cache, damit Nutzer auch dann auf diese Inhalte zugreifen können, wenn das Gerät keine Netzwerkverbindung hat.

Die Room-Persistenzbibliothek bietet eine Abstraktionsebene über SQLite, um einen flüssigen Datenbankzugriff zu ermöglichen und gleichzeitig die volle Leistung von SQLite zu nutzen. Insbesondere bietet Room die folgenden Vorteile:

  • Überprüfung von SQL-Abfragen zur Kompilierzeit
  • Praktische Annotationen, die sich wiederholenden und fehleranfälligen Boilerplate-Code minimieren
  • Optimierte Datenbankmigrationspfade

Aus diesen Gründen empfehlen wir dringend, Room anstelle der direkten Verwendung der SQLite-APIs zu verwenden.

Einrichtung

Wenn Sie Room in Ihrer App verwenden möchten, fügen Sie der Datei build.gradle Ihrer App die folgenden Abhängigkeiten hinzu.

Kotlin

dependencies {
    val room_version = "2.8.4"

    implementation("androidx.room:room-runtime:$room_version")

    // If this project uses any Kotlin source, use Kotlin Symbol Processing (KSP)
    // See Add the KSP plugin to your project
    ksp("androidx.room:room-compiler:$room_version")

    // If this project only uses Java source, use the Java annotationProcessor
    // No additional plugins are necessary
    annotationProcessor("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")
}

Groovy

dependencies {
    def room_version = "2.8.4"

    implementation "androidx.room:room-runtime:$room_version"

    // If this project uses any Kotlin source, use Kotlin Symbol Processing (KSP)
    // See KSP Quickstart to add KSP to your build
    ksp "androidx.room:room-compiler:$room_version"

    // If this project only uses Java source, use the Java annotationProcessor
    // No additional plugins are necessary
    annotationProcessor "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"
}

Hauptkomponenten

Room besteht aus drei Hauptkomponenten:

  • Die Datenbankklasse, die die Datenbank enthält und als Hauptzugangspunkt für die zugrunde liegende Verbindung zu den persistenten Daten Ihrer App dient.
  • Datenentitäten, die Tabellen in der Datenbank Ihrer App darstellen.
  • Data Access Objects (DAOs), die Methoden bereitstellen, mit denen Ihre App Daten in der Datenbank abfragen, aktualisieren, einfügen und löschen kann.

Die Datenbankklasse stellt Ihrer App Instanzen der DAOs zur Verfügung, die mit dieser Datenbank verknüpft sind. Die App kann die DAOs wiederum verwenden, um Daten aus der Datenbank als Instanzen der zugehörigen Datenentitätsobjekte abzurufen. Die App kann auch die definierten Datenentitäten verwenden, um Zeilen aus den entsprechenden Tabellen zu aktualisieren oder neue Zeilen zum Einfügen zu erstellen. Abbildung 1 veranschaulicht die Beziehung zwischen den verschiedenen Komponenten von Room.

Abbildung 1. Diagramm der Architektur der Room-Bibliothek

Implementierungsbeispiel

In diesem Abschnitt wird eine Beispielimplementierung einer Room-Datenbank 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 App 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 mit Room Entitäten definieren.

Data Access Object (DAO)

Mit dem folgenden Code wird ein DAO namens UserDao definiert. UserDao stellt die Methoden bereit, mit denen der Rest der App mit Daten in der Tabelle user interagiert.

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 Room DAOs auf Daten zugreifen.

Datenbank

Mit dem folgenden Code wird eine AppDatabase-Klasse definiert, die die Datenbank enthält. AppDatabase definiert die Datenbankkonfiguration und dient als Hauptzugriffspunkt der App für die persistenten Daten. Die Datenbankklasse muss die folgenden Bedingungen erfüllen:

  • Die Klasse muss mit einer @Database-Annotation versehen sein, die ein entities -Array enthält, in dem alle mit der Datenbank verknüpften Datenentitäten aufgeführt sind.
  • Die Klasse muss eine abstrakte Klasse sein, die RoomDatabase erweitert.
  • Für jede DAO-Klasse, die mit der Datenbank verknüpft ist, 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 App in einem einzelnen Prozess ausgeführt wird, sollten Sie beim Instanziieren eines AppDatabase -Objekts das Singleton-Entwurfsmuster verwenden. Jede RoomDatabase Instanz ist relativ teuer und Sie benötigen selten Zugriff auf mehrere Instanzen innerhalb eines einzelnen Prozesses.

Wenn Ihre App in mehreren Prozessen ausgeführt wird, fügen Sie enableMultiInstanceInvalidation() in den Aufruf des Datenbank-Builders ein. Wenn Sie also in jedem Prozess eine Instanz von AppDatabase haben, können Sie die freigegebene Datenbankdatei in einem Prozess ungültig machen, und diese Ungültigmachung wird automatisch an die Instanzen von AppDatabase in anderen Prozessen weitergegeben.

Nutzung

Nachdem Sie die Datenentität, das 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();

Anschließend können Sie die abstrakten Methoden aus AppDatabase verwenden, um eine Instanz des DAO abzurufen. Mit den Methoden der DAO-Instanz können Sie wiederum mit der Datenbank interagieren:

Kotlin

val userDao = db.userDao()
val users: List<User> = userDao.getAll()

Java

UserDao userDao = db.userDao();
List<User> users = userDao.getAll();

Zusätzliche Ressourcen

Weitere Informationen zu Room finden Sie in den folgenden zusätzlichen Ressourcen:

Beispiele

Codelabs

Blogs