1:n-Beziehungen definieren und abfragen

Eine 1:n-Beziehung zwischen zwei Entitäten ist eine Beziehung, bei der jede Instanz der übergeordneten Entität null oder mehr Instanzen der untergeordneten Entität entspricht, aber jede Instanz der untergeordneten Entität kann nur genau einer Instanz der übergeordneten Entität entsprechen.

Nehmen wir als Beispiel eine Musikstreaming-App, in der Nutzer ihre Songs in Playlists organisieren können. Jeder Nutzer kann beliebig viele Playlists erstellen, aber jede Playlist wird von genau einem Nutzer erstellt. Daher besteht eine 1:n-Beziehung zwischen der Entität User und der Entität Playlist.

So definieren und fragen Sie 1:n-Beziehungen in Ihrer Datenbank ab:

  1. Beziehung definieren: Erstellen Sie Klassen für beide Entitäten, wobei die untergeordnete Entität auf den Primärschlüssel der übergeordneten Entität verweist.
  2. Entitäten abfragen: Modellieren Sie die Beziehung in einer neuen Datenklasse und implementieren Sie eine Funktion zum Abrufen der zugehörigen Daten.

Beziehung definieren

Um eine 1:n-Beziehung zu definieren, erstellen Sie zuerst eine Klasse für jede Entität. Wie bei einer 1:1-Beziehung muss die untergeordnete Entität eine Variable enthalten, die auf den Primärschlüssel der übergeordneten Entität verweist.

@Entity
data class User(
    @PrimaryKey val userId: Long,
    val name: String,
    val age: Int
)

@Entity
data class Playlist(
    @PrimaryKey val playlistId: Long,
    val userCreatorId: Long,
    val playlistName: String
)

Entitäten abfragen

Wenn Sie die Liste der Nutzer und die entsprechenden Playlists abfragen möchten, müssen Sie zuerst die 1:n-Beziehung zwischen den beiden Entitäten modellieren.

Erstellen Sie dazu eine neue Datenklasse. Jede Instanz dieser Klasse enthält eine Instanz der übergeordneten Entität und eine Liste aller entsprechenden Instanzen der untergeordneten Entität. Fügen Sie der Property, die die Liste der untergeordneten Entitäten darstellt, die @Relation Annotation hinzu. Legen Sie parentColumns auf den Namen der Primärschlüsselspalte der übergeordneten Entität und entityColumns auf den Namen der Spalte der untergeordneten Entität fest, die auf den Primärschlüssel der übergeordneten Entität verweist.

data class UserWithPlaylists(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["userId"],
        entityColumns = ["userCreatorId"]
    )
    val playlists: List<Playlist>
)

Fügen Sie schließlich der Klasse des Data Access Object (DAO) eine Funktion hinzu, die alle Instanzen der Datenklasse zurückgibt, die die übergeordnete und die untergeordnete Entität zusammenführt. Fügen Sie die @Transaction Annotation hinzu, damit Room den gesamten Vorgang atomar ausführt. Diese Annotation ist erforderlich, da die Funktion zwei Abfragen in Room ausführen muss.

@Transaction
@Query("SELECT * FROM User")
suspend fun getUsersWithPlaylists(): List<UserWithPlaylists>

Zusammengesetzte Schlüssel

Wenn Sie die Beziehung mit zusammengesetzten Schlüsseln definieren, geben Sie in parentColumns und entityColumns mehrere Spalten an. Die Reihenfolge der Spalten in parentColumns muss mit der Reihenfolge der Spalten in entityColumns übereinstimmen.

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

@Entity
data class Playlist(
    @PrimaryKey val playlistId: Long,
    val userFirstName: String,
    val userLastName: String,
    val playlistName: String
)

data class UserWithPlaylists(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["firstName", "lastName"],
        entityColumns = ["userFirstName", "userLastName"]
    )
    val playlists: List<Playlist>
)