Daten mithilfe von Zimmerentitäten definieren

Wenn Sie die Room-Persistenzbibliothek zum Speichern der Daten Ihrer App verwenden, definieren Sie Entitäten, um die Objekte darzustellen, die Sie speichern möchten. Jede Entität entspricht einer Tabelle in der zugehörigen Room-Datenbank und jede Instanz einer Entität stellt eine Datenzeile in der entsprechenden Tabelle dar.

Mit Room-Entitäten können Sie Ihr Datenbankschema definieren, ohne SQL-Code schreiben zu müssen.

Anatomie einer Entität

Sie definieren jede Room-Entität als Klasse, die mit @Entity annotiert ist. Eine Room -Entität enthält Eigenschaften für jede Spalte in der entsprechenden Tabelle in der Datenbank, einschließlich einer oder mehrerer Spalten, aus denen der Primärschlüssel besteht.

Der folgende Code ist ein Beispiel für eine Entität, die eine User-Tabelle mit Spalten für ID, Vorname und Nachname definiert:

@Entity
data class User(
    @PrimaryKey val id: Int,
    val firstName: String,
    val lastName: String
)

Standardmäßig verwendet Room den Klassennamen als Namen der Datenbanktabelle. Wenn die Tabelle einen anderen Namen haben soll, legen Sie die tableName Eigenschaft der @Entity Annotation fest. Ebenso verwendet Room standardmäßig die Eigenschaftsnamen als Spaltennamen in der Datenbank. Wenn eine Spalte einen anderen Namen haben soll, fügen Sie der Eigenschaft die @ColumnInfo Annotation hinzu und legen Sie die name Eigenschaft fest. Im folgenden Beispiel werden benutzerdefinierte Namen für eine Tabelle und ihre Spalten gezeigt:

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "first_name") val firstName: String,
    @ColumnInfo(name = "last_name") val lastName: String
)

Primärschlüssel definieren

Sie müssen für jede Room-Entität einen Primärschlüssel definieren, um jede Zeile in der entsprechenden Datenbanktabelle eindeutig zu identifizieren. Annotieren Sie dazu eine einzelne Spalte mit @PrimaryKey:

@PrimaryKey val id: Int

Zusammengesetzten Primärschlüssel definieren

Wenn Instanzen einer Entität durch eine Kombination aus mehreren Spalten eindeutig identifiziert werden müssen, können Sie einen zusammengesetzten Primärschlüssel definieren, indem Sie diese Spalten in der primaryKeys Eigenschaft von @Entity auflisten:

@Entity(primaryKeys = ["firstName", "lastName"])
data class User(
    val firstName: String,
    val lastName: String
)

Eigenschaften ignorieren

Standardmäßig erstellt Room eine Spalte für jede in der Entität definierte Eigenschaft. Wenn Sie verhindern möchten, dass Room eine Eigenschaft beibehält, annotieren Sie sie mit @Ignore:

@Entity
data class User(
    @PrimaryKey val id: Int,
    val firstName: String,
    val lastName: String,
    @Ignore val picture: Bitmap? = null
)

Wenn eine Entität Eigenschaften von einer übergeordneten Entität erbt, verwenden Sie die ignoredColumns Eigenschaft der @Entity Annotation:

open class User {
    var picture: Bitmap? = null
}

@Entity(ignoredColumns = ["picture"])
data class RemoteUser(
    @PrimaryKey val id: Int,
    val hasVpn: Boolean
) : User()

Room unterstützt mehrere Annotationen, mit denen Sie in Ihren Datenbanktabellen nach Details suchen können.

Volltextsuche unterstützen

Wenn Ihre App eine schnelle Volltextsuche (Full-Text Search, FTS) erfordert, sichern Sie Ihre Entitäten mit einer virtuellen Tabelle. Verwenden Sie die SQLite-Erweiterung FTS3 oder FTS4 oder die SQLite-Erweiterung FTS5.

Wenn Sie diese Funktion verwenden möchten, fügen Sie einer Entität die @Fts3, @Fts4 oder @Fts5 Annotation hinzu.

// Use `@Fts3` only if your app has strict disk space requirements.
@Fts4
@Entity(tableName = "users")
data class User(
    // Specifying a primary key for an FTS-table-backed entity is optional,
    // but if you include one, it must an INTEGER type and column name "rowid".
    @PrimaryKey @ColumnInfo(name = "rowid") val id: Long,
    @ColumnInfo(name = "first_name") val firstName: String
)

Mit der Option tokenizer können Sie anpassen, wie Datenbankinformationen in FTS-Tabellen in Tokens zerlegt werden. Room bietet über FtsOptions mehrere integrierte Tokenizer, darunter TOKENIZER_SIMPLE, TOKENIZER_PORTER und TOKENIZER_UNICODE61:

@Fts4(tokenizer = FtsOptions.TOKENIZER_UNICODE61)
@Entity(tableName = "users")
data class User(
    @PrimaryKey @ColumnInfo(name = "rowid") val id: Long,
    @ColumnInfo(name = "first_name") val firstName: String
)

Room bietet mehrere weitere Optionen zum Definieren von FTS-gesicherten Entitäten, darunter die Sortierung von Ergebnissen, das Entfernen von Indexen aus Spalten und Tabellen, die als externer Inhalt verwaltet werden. Weitere Informationen zu diesen Optionen finden Sie in der FtsOptions Referenz.

Bestimmte Spalten indexieren

Wenn Sie AndroidSQLiteDriver verwenden und SDK Versionen unterstützen müssen, die keine FTS3-, FTS4- oder FTS5-Tabellen-gesicherten Entitäten unterstützen, können Sie bestimmte Spalten in der Datenbank indexieren, um Ihre Abfragen zu beschleunigen. Wenn Sie BundledSQLiteDriver verwenden, unterstützt Room alle FTS-Versionen unabhängig von der Android SDK-Version.

Wenn Sie einer Entität Indexe hinzufügen möchten, fügen Sie die indices Eigenschaft in die @Entity Annotation ein. Listen Sie die Spaltennamen auf, die in den Index oder zusammengesetzten Index aufgenommen werden sollen. Das folgende Code-Snippet zeigt, wie Sie Indexe hinzufügen:

@Entity(indices = [Index(value = ["last_name", "address"])])
data class User(
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "first_name") val firstName: String,
    @ColumnInfo(name = "last_name") val lastName: String,
    val address: String?,
)

Manchmal müssen bestimmte Spalten oder Spaltengruppen in einer Datenbank eindeutige Werte enthalten. Wenn Sie diese Eindeutigkeit erzwingen möchten, legen Sie die unique Eigenschaft von einer @Index Annotation auf true fest. Das folgende Codebeispiel zeigt, wie Sie diese Eindeutigkeit erzwingen:

@Entity(indices = [Index(value = ["first_name", "last_name"], unique = true)])
data class User(
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "first_name") val firstName: String,
    @ColumnInfo(name = "last_name") val lastName: String,
)