Definiowanie relacji jeden do jednego i wysyłanie zapytań dotyczących takich relacji

Relacja jeden do jednego między 2 encjami to relacja, w której każde wystąpienie encji nadrzędnej odpowiada dokładnie 1 wystąpieniu encji podrzędnej i odwrotnie.

Rozważmy na przykład aplikację do odtwarzania strumieniowego muzyki, w której użytkownik ma bibliotekę utworów. Każdy użytkownik ma tylko 1 bibliotekę, a każda biblioteka odpowiada dokładnie 1 użytkownikowi. Dlatego między encją User a encją Library występuje relacja jeden do jednego.

Aby zdefiniować relacje jeden do jednego w bazie danych i wysyłać do nich zapytania:

  1. Zdefiniuj relację: utwórz klasy dla obu encji i upewnij się, że jedna z nich odwołuje się do klucza podstawowego drugiej.
  2. Wyślij zapytanie o encje: modeluj relację w nowej klasie danych, i utwórz funkcję do pobierania powiązanych danych.

Zdefiniuj relację

Aby zdefiniować relację jeden do jednego, najpierw utwórz klasę dla każdej z 2 encji. Jedna z encji musi zawierać zmienną, która odwołuje się do klucza podstawowego drugiej encji.

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

@Entity
data class Library(
    @PrimaryKey val libraryId: Long,
    val userOwnerId: Long
)

Wyślij zapytanie o encje

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

Aby modelować relację, utwórz nową klasę danych, w której każde wystąpienie zawiera wystąpienie encji nadrzędnej i odpowiadającej jej encji podrzędnej. Dodaj do encji podrzędnej adnotację @Relation. 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 UserAndLibrary(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["userId"],
        entityColumns = ["userOwnerId"]
    )
    val library: Library
)

Na koniec dodaj do klasy obiektu umożliwiającego dostęp do danych (DAO) funkcję, która zwraca wszystkie instancje klasy danych, która łączy encję nadrzędną z encją podrzędną. Dodaj adnotację @Transaction, aby mieć pewność, że Room wykona całą operację atomowo, ponieważ ta funkcja wymaga od Room uruchomienia 2 zapytań.

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

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 Library(
    @PrimaryKey val libraryId: Long,
    val userFirstName: String,
    val userLastName: String
)

data class UserAndLibrary(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["firstName", "lastName"],
        entityColumns = ["userFirstName", "userLastName"]
    )
    val library: Library
)