В разработке для Android Room — это библиотека, которая обеспечивает уровень абстракции над SQLite для операций с базой данных. Одной из ключевых особенностей Room является возможность определять отношения между сущностями (таблицами) в базе данных. В этой статье мы обсудим три типа отношений, которые можно определить в Room: один ко многим, многие ко многим и один к одному.

Связь «один ко многим»

Отношение «один ко многим» — это отношение между двумя объектами, в котором один объект имеет одну запись, которая связана с несколькими записями в другом объекте. Например, в базе данных сотрудников у каждого сотрудника есть только один отдел, но в каждом отделе может быть несколько сотрудников.

Чтобы определить отношение «один ко многим» в Room, мы можем использовать аннотацию @ForeignKey для дочерней сущности и аннотацию @Relation для родительской сущности.

Вот пример того, как определить отношение «один ко многим» между сущностью «Сотрудник» и «Отдел»:

@Entity
data class Employee(
    @PrimaryKey val id: Int,
    val name: String,
    val departmentId: Int
)

@Entity
data class Department(
    @PrimaryKey val id: Int,
    val name: String
)

data class EmployeeWithDepartment(
    @Embedded val employee: Employee,
    @Relation(
        parentColumn = "departmentId",
        entityColumn = "id"
    )
    val department: Department
)

В этом примере объект Employee имеет внешний ключ departmentId, который ссылается на id объекта Department. Класс данных EmployeeWithDepartment использует аннотацию @Embedded для встраивания объекта Employee, а аннотацию @Relation — для определения взаимосвязи между объектами Employee и Department.

Связь «многие ко многим»

Связь «многие ко многим» — это связь между двумя объектами, при которой несколько записей в одном объекте связаны с несколькими записями в другом объекте. Например, в базе данных книг и авторов у каждой книги может быть несколько авторов, и каждый автор может написать несколько книг.

Чтобы определить отношение «многие ко многим» в Room, нам нужно создать отдельный объект, представляющий отношение между двумя объектами. Этот объект часто называют «таблицей соединения» и содержит внешние ключи к первичным ключам связанных объектов.

Вот пример того, как определить отношение «многие ко многим» между сущностью «Книга» и «Автор»:

@Entity
data class Book(
    @PrimaryKey val id: Int,
    val title: String
)

@Entity
data class Author(
    @PrimaryKey val id: Int,
    val name: String
)

@Entity
data class BookAuthor(
    @PrimaryKey(autoGenerate = true) val id: Int,
    val bookId: Int,
    val authorId: Int
)

В этом примере объект BookAuthor представляет связь между объектами Book и Author. У него есть два внешних ключа bookId и authorId, которые ссылаются на первичные ключи сущностей Book и Author соответственно.

Отношения один к одному

Связь «один к одному» — это связь между двумя объектами, при которой одна запись в одном объекте связана с одной и только одной записью в другом объекте. Например, в базе данных пользователей и их личной информации каждый пользователь может иметь один и только один набор личной информации.

Чтобы определить отношение «один к одному» в Room, мы можем использовать аннотацию @ForeignKey для дочернего объекта и аннотацию @Relation для родительского объекта.

Вот пример того, как определить отношение «один к одному» между пользователем и сущностью PersonalInfo:

@Entity
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    val personalInfoId: Int
)

@Entity
data class PersonalInfo(
    @PrimaryKey val id: Int,
    val address: String,
    val phoneNumber: String
)

data class UserWithPersonalInfo(
    @Embedded val user: User,
    @Relation(
        parentColumn = "personalInfoId",
        entityColumn = "id"
    )
    val personalInfo: PersonalInfo
)

В этом примере объект User имеет внешний ключ personalInfoId, который ссылается на id объекта PersonalInfo. Класс данных UserWithPersonalInfo использует аннотацию @Embedded для встраивания объекта User и аннотацию @Relation для указания отношения между объектами User и PersonalInfo.

В заключение, Room в Android предоставляет мощный и простой в использовании API для определения отношений между сущностями в базе данных SQLite. С помощью аннотаций @ForeignKey, @Relation и @Embedded разработчики могут легко определять отношения "один ко многим", "многие ко многим" и "один к одному" в своей базе данных.