Definiowanie relacji jeden-do-wielu i wysyłanie zapytań do nich

Relacja jeden do wielu między 2 encjami to relacja, w której każde wystąpienie encji nadrzędnej odpowiada 0 lub większej liczbie wystąpień encji podrzędnej, ale każde wystąpienie encji podrzędnej może odpowiadać tylko 1 wystąpieniu encji nadrzędnej.

Załóżmy, że w aplikacji do odtwarzania strumieniowego muzyki użytkownik może porządkować utwory na playlistach. Każdy użytkownik może utworzyć dowolną liczbę playlist, ale każdą playlistę tworzy dokładnie 1 użytkownik. Dlatego między encją User a encją Playlist występuje relacja jeden do wielu.

Aby zdefiniować relacje jeden do wielu w bazie danych i wysyłać do niej zapytania:

  1. Zdefiniuj relację: utwórz klasy dla obu encji, przy czym encja podrzędna odwołuje się do klucza podstawowego encji nadrzędnej.
  2. Wyślij zapytanie o encje: modeluj relację w nowej klasie danych i zaimplementuj funkcję pobierania powiązanych danych.

Zdefiniuj relację

Aby zdefiniować relację jeden do wielu, najpierw utwórz klasę dla każdej encji. Podobnie jak w przypadku relacji jeden do jednego encja podrzędna musi zawierać zmienną, która odwołuje się do klucza podstawowego encji nadrzędnej.

@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
)

Wyślij zapytanie o encje

Aby wysłać zapytanie o listę użytkowników i odpowiadające im playlisty, musisz najpierw modelować relację jeden do wielu między tymi 2 encjami.

Aby modelować relację, utwórz nową klasę danych. Każde wystąpienie tej klasy zawiera wystąpienie encji nadrzędnej i listę wszystkich odpowiadających jej wystąpień encji podrzędnej. Dodaj adnotację @Relation do właściwości, która reprezentuje listę encji podrzędnych. Ustaw parentColumns na nazwę kolumny klucza podstawowego encji nadrzędnej , a entityColumns na nazwę kolumny encji podrzędnej , która odwołuje się do klucza podstawowego encji nadrzędnej.

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

Na koniec dodaj do klasy obiektu umożliwiającego dostęp do danych (DAO) funkcję, która zwraca wszystkie wystąpienia klasy danych łączącej encję nadrzędną i encję podrzędną. Dodaj adnotację @Transaction, aby Room wykonywał całą operację atomowo. Ta adnotacja jest niezbędna, ponieważ funkcja wymaga, aby Room uruchomił 2 zapytania.

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

Klucze złożone

Jeśli zdefiniujesz relację za pomocą kluczy złożonych, określ wiele kolumn w parentColumns i entityColumns. Kolejność kolumn w parentColumns musi być zgodna z kolejnością kolumn w entityColumns.

@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>
)