Отношение "один к одному" между двумя объектами означает, что каждому экземпляру родительского объекта соответствует ровно один экземпляр дочернего объекта, и наоборот.
Например, в приложении для потоковой передачи музыки у пользователя может быть собственная библиотека песен. У каждого пользователя только одна библиотека, и каждая библиотека принадлежит только одному пользователю. Таким образом, между объектом User и объектом Library существует связь "один к одному".
Чтобы определить и запросить отношения "один к одному" в базе данных, выполните следующие действия:
- Определите связь. Создайте классы для обоих объектов и убедитесь, что один из них ссылается на первичный ключ другого.
- Запросите сущности. Создайте модель отношений в новом классе данных и напишите функцию для получения связанных данных.
Как определить связь
Чтобы задать связь "один к одному", сначала создайте класс для каждого из двух объектов. Одна из сущностей должна содержать переменную, которая ссылается на первичный ключ другой сущности.
@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 )