Отношение «один ко многим» между двумя сущностями — это отношение, при котором каждому экземпляру родительской сущности соответствует ноль или более экземпляров дочерней сущности, но каждому экземпляру дочерней сущности может соответствовать только один экземпляр родительской сущности.
В примере с приложением для потоковой передачи музыки предположим, что пользователь может организовывать свои песни в плейлисты. Каждый пользователь может создать столько плейлистов, сколько захочет, но каждый плейлист создаст ровно один пользователь. Следовательно, существует отношение «один ко многим» между сущностью User и сущностью Playlist .
Выполните следующие шаги, чтобы определить и запросить связи «один ко многим» в вашей базе данных:
- Определите взаимосвязь : создайте классы для обеих сущностей, при этом дочерняя сущность будет ссылаться на первичный ключ родительской сущности.
- Запрос к сущностям : Смоделируйте взаимосвязь в новом классе данных и реализуйте функцию для получения связанных данных.
Определите взаимоотношения
Для определения отношения «один ко многим» сначала создайте класс для каждой сущности. Как и в отношении «один к одному», дочерняя сущность должна содержать переменную, которая ссылается на первичный ключ родительской сущности.
@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 )
Запрос к сущностям
Для получения списка пользователей и соответствующих плейлистов необходимо сначала смоделировать отношение «один ко многим» между этими двумя сущностями.
Для моделирования связи создайте новый класс данных. Каждый экземпляр этого класса содержит экземпляр родительской сущности и список всех соответствующих экземпляров дочерних сущностей. Добавьте аннотацию @Relation к свойству, представляющему список дочерних сущностей. Установите parentColumns равным имени столбца первичного ключа родительской сущности, а entityColumns — имени столбца дочерней сущности, ссылающегося на первичный ключ родительской сущности.
data class UserWithPlaylists( @Embedded val user: User, @Relation( parentColumns = ["userId"], entityColumns = ["userCreatorId"] ) val playlists: List<Playlist> )
Наконец, добавьте в класс объекта доступа к данным (DAO) функцию, которая возвращает все экземпляры класса данных, связывающие родительскую и дочернюю сущности. Добавьте аннотацию @Transaction , чтобы Room выполнял всю операцию атомарно. Эта аннотация необходима, поскольку функция требует от Room выполнения двух запросов.
@Transaction @Query("SELECT * FROM User") suspend fun getUsersWithPlaylists(): List<UserWithPlaylists>
Составные ключи
Если вы определяете связь с помощью составных ключей, укажите несколько столбцов в parentColumns и entityColumns . Порядок столбцов в parentColumns должен совпадать с порядком столбцов в 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> )