Связь «один ко многим» между двумя объектами — это связь, при которой каждый экземпляр родительской сущности соответствует нулю или более экземплярам дочерней сущности, но каждый экземпляр дочерней сущности может соответствовать только одному экземпляру родительской сущности.
Предположим, что в примере приложения для потоковой передачи музыки у пользователя есть возможность организовывать свои песни в списки воспроизведения. Каждый пользователь может создать столько списков воспроизведения, сколько пожелает, но каждый список воспроизведения создает ровно один пользователь. Следовательно, между объектом 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
)
Ява
@Entity
public class User {
@PrimaryKey public long userId;
public String name;
public int age;
}
@Entity
public class Playlist {
@PrimaryKey public long playlistId;
public long userCreatorId;
public String playlistName;
}
Запросить сущности
Чтобы запросить список пользователей и соответствующие списки воспроизведения, вы должны сначала смоделировать связь «один ко многим» между двумя объектами.
Для этого создайте новый класс данных, где каждый экземпляр содержит экземпляр родительской сущности и список всех соответствующих экземпляров дочерней сущности. Добавьте аннотацию @Relation
к экземпляру дочерней сущности, при этом для параметра parentColumn
будет задано имя столбца первичного ключа родительской сущности, а entityColumn
задано имя столбца дочерней сущности, который ссылается на первичный ключ родительской сущности.
Котлин
data class UserWithPlaylists(
@Embedded val user: User,
@Relation(
parentColumn = "userId",
entityColumn = "userCreatorId"
)
val playlists: List<Playlist>
)
Ява
public class UserWithPlaylists {
@Embedded public User user;
@Relation(
parentColumn = "userId",
entityColumn = "userCreatorId"
)
public List<Playlist> playlists;
}
Наконец, добавьте в класс DAO метод, который возвращает все экземпляры класса данных, объединяющего родительский объект и дочерний объект. Этот метод требует, чтобы Room выполнил два запроса, поэтому добавьте к этому методу аннотацию @Transaction
, чтобы вся операция выполнялась атомарно.
Котлин
@Transaction
@Query("SELECT * FROM User")
fun getUsersWithPlaylists(): List<UserWithPlaylists>
Ява
@Transaction
@Query("SELECT * FROM User")
public List<UserWithPlaylists> getUsersWithPlaylists();