0Pricing
Kotlin Academy · Урок

DAO Exposed: классы сущностей и связи

Используйте API DAO для отображения таблиц на классы сущностей и работы со связями.

«DAO Exposed: классы сущностей и связи» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.

Что такое слой DAO Exposed

Слой DAO (объектов доступа к данным) в Exposed оборачивает DSL запросов API в стиле Active Record. Вы определяете подклассы Entity, сопоставленные со строками таблицы, и напрямую читаете и изменяете свойства экземпляров сущностей.

Определение сущности

Свяжите LongIdTable с подклассом Entity. У каждого класса сущностей есть объект-компаньон EntityClass, который обрабатывает запросы:

object Users : LongIdTable("users") {
    val name  = varchar("name", 100)
    val email = varchar("email", 255)
}

class User(id: EntityID<Long>) : LongEntity(id) {
    companion object : LongEntityClass<User>(Users)
    var name  by Users.name
    var email by Users.email
}

Создание сущности

Используйте Entity.new { } внутри transaction { }, чтобы создать новую строку и получить экземпляр сущности:

val alice: User = transaction {
    User.new {
        name  = "Alice"
        email = "alice@example.com"
    }
}

Поиск сущностей

Объект-компаньон EntityClass предоставляет методы поиска: findById(id), all() и find { condition }:

transaction {
    val user: User? = User.findById(1L)
    val allUsers: SizedIterable<User> = User.all()
    val filtered = User.find { Users.name like "Al%" }.toList()
}

Изменение сущности

Прочитайте сущность, измените её свойства внутри транзакции, и Exposed автоматически сформирует UPDATE при фиксации транзакции:

transaction {
    val user = User.findById(1L) ?: error("Not found")
    user.name = "Alice Smith"
    // UPDATE issued on transaction commit
}

Удаление сущности

Вызовите entity.delete() внутри транзакции, чтобы удалить соответствующую строку:

transaction {
    User.findById(5L)?.delete()
}

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

Свяжите дочернюю сущность с родительской с помощью reference() в таблице и делегируемого свойства by в сущности. Получите список дочерних сущностей из родительской через referrersOn:

object Posts : LongIdTable("posts") {
    val title    = varchar("title", 300)
    val authorId = reference("author_id", Users)
}
class Post(id: EntityID<Long>) : LongEntity(id) {
    companion object : LongEntityClass<Post>(Posts)
    var title  by Posts.title
    var author by User referencedOn Posts.authorId
}
// On User entity:
val posts by Post referrersOn Posts.authorId

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

Используйте промежуточную таблицу связей. Представьте её как EntityClass и обращайтесь к обеим сторонам с помощью via():

object UserRoles : Table("user_roles") {
    val user = reference("user_id", Users)
    val role = reference("role_id", Roles)
}
// On User entity:
var roles by Role via UserRoles

Жадная и ленивая загрузка

По умолчанию Exposed загружает связанные сущности лениво — при каждом обращении выполняется SQL-запрос. Используйте load() или with() для жадной загрузки связей и устранения проблем с запросами N+1:

transaction {
    User.all().with(User::posts).forEach { user ->
        println("${user.name}: ${user.posts.count()} posts")
    }
}

Кэширование внутри транзакции

Exposed кэширует экземпляры сущностей внутри транзакции. При обращении к одной и той же сущности по ID несколько раз в рамках одной транзакции возвращается тот же объект в памяти — без лишних обращений к базе данных.

Когда использовать DAO, а когда — DSL запросов

Используйте слой DAO, когда нужен объектно-ориентированный доступ и работа со связями. Используйте DSL запросов для массовых операций, сложных объединений, агрегаций или когда важна производительность и нужен точный контроль над SQL.

Быстрая проверка

Как с помощью DAO Exposed создать новую строку и сразу получить экземпляр сущности?

Повторение: DAO Exposed — классы сущностей и связи

Основные выводы:

  • Свяжите LongIdTable с подклассом LongEntity; свойства делегируются определениям столбцов
  • Entity.new { } — создать; findById(), find { }, all() — выполнить запрос; entity.delete() — удалить
  • Связь «один ко многим»: referencedOn (сторона дочерней сущности), referrersOn (сторона родительской сущности)
  • Связь «многие ко многим»: таблица связей + via()
  • Используйте with() для жадной загрузки связей и устранения запросов N+1

Часто задаваемые вопросы

Урок «DAO Exposed: классы сущностей и связи» бесплатный?

Да — полный текст урока «DAO Exposed: классы сущностей и связи» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.

Чему я научусь в уроке «DAO Exposed: классы сущностей и связи»?

Используйте API DAO для отображения таблиц на классы сущностей и работы со связями. Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Kotlin Academy?

Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «DAO Exposed: классы сущностей и связи»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Kotlin Academy?

Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Настройка Exposed: подключение к базе данных и DSL транзакций
  2. Определение таблиц с DSL Table
  3. CRUD с DSL запросов: insert, select, update, delete
  4. DAO Exposed: классы сущностей и связи
← Назад к Kotlin Academy