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:
- Zdefiniuj relację: utwórz klasy dla obu encji, przy czym encja podrzędna odwołuje się do klucza podstawowego encji nadrzędnej.
- 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> )