Определение и запрос отношений «один к одному»

Однозначное отношение между двумя сущностями — это отношение, при котором каждому экземпляру родительской сущности соответствует ровно один экземпляр дочерней сущности, и обратное также верно.

Например, рассмотрим приложение для потоковой передачи музыки, где у пользователя есть собственная библиотека песен. У каждого пользователя только одна библиотека, и каждая библиотека соответствует ровно одному пользователю. Следовательно, существует однозначное соответствие между сущностью User и сущностью Library .

Выполните следующие шаги, чтобы определить и запросить отношения «один к одному» в вашей базе данных:

  1. Определите взаимосвязь : создайте классы для обеих сущностей и убедитесь, что одна ссылается на первичный ключ другой.
  2. Запрос к сущностям : смоделируйте взаимосвязь в новом классе данных и создайте функцию для получения связанных данных.

Определите взаимоотношения

Для определения отношения «один к одному» сначала создайте класс для каждой из двух сущностей. Одна из сущностей должна содержать переменную, которая ссылается на первичный ключ другой сущности.

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

Запрос к сущностям

Для запроса списка пользователей и соответствующих библиотек необходимо сначала смоделировать отношение «один к одному» между этими двумя сущностями.

Для моделирования связи создайте новый класс данных, в котором каждый экземпляр содержит экземпляр родительской сущности и соответствующий дочерний экземпляр. Добавьте аннотацию @Relation к дочерней сущности. Установите parentColumns равным имени столбца первичного ключа родительской сущности, а entityColumns — имени столбца дочерней сущности, который ссылается на первичный ключ родительской сущности.

data class UserAndLibrary(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["userId"],
        entityColumns = ["userOwnerId"]
    )
    val library: Library
)

Наконец, добавьте в класс объекта доступа к данным (DAO) функцию, которая возвращает все экземпляры класса данных, связывающего родительскую сущность с дочерней. Добавьте аннотацию @Transaction , чтобы гарантировать атомарное выполнение всей операции Room, поскольку эта функция требует от Room выполнения двух запросов.

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

Составные ключи

Если вы определяете связь с помощью составных ключей, укажите несколько столбцов в parentColumns и entityColumns . Порядок столбцов в parentColumns должен совпадать с порядком столбцов в 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
)