0Pricing
Kotlin Academy · Урок

Определение таблиц с DSL Table

Определяйте типизированные схемы таблиц со столбцами, первичными и внешними ключами.

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

Объекты таблиц Exposed

В Exposed таблицы базы данных представлены одиночными объектами Kotlin object, расширяющими Table (DSL запросов) или IntIdTable/LongIdTable/UUIDTable (слой DAO). Определения столбцов являются свойствами Kotlin.

Базовое определение таблицы

Расширьте Table и определите столбцы с помощью встроенных фабричных функций для столбцов:

import org.jetbrains.exposed.sql.Table

object Users : Table("users") {
    val id    = long("id").autoIncrement()
    val name  = varchar("name", 100)
    val email = varchar("email", 255).uniqueIndex()
    val age   = integer("age").nullable()

    override val primaryKey = PrimaryKey(id)
}

Типы столбцов

Exposed предоставляет фабричные функции для распространённых типов SQL:

  • integer("col"), long("col"), short("col")
  • varchar("col", length), text("col")
  • bool("col"), double("col"), decimal("col", precision, scale)
  • datetime("col"), date("col"), timestamp("col")
  • blob("col"), uuid("col"), binary("col", length)

Столбцы, допускающие NULL

Вызовите .nullable() для любого столбца, чтобы разрешить значения NULL. Тип Kotlin станет допускающим значение null (String? вместо String):

object Products : Table("products") {
    val id          = long("id").autoIncrement()
    val name        = varchar("name", 200)
    val description = text("description").nullable()
    override val primaryKey = PrimaryKey(id)
}

Значения по умолчанию

Используйте .default(value) для значения по умолчанию на стороне Kotlin (применяется перед вставкой) или .defaultExpression(expr) для значения SQL по умолчанию на стороне базы данных:

object Orders : Table("orders") {
    val id        = long("id").autoIncrement()
    val status    = varchar("status", 20).default("PENDING")
    val createdAt = datetime("created_at")
        .defaultExpression(CurrentDateTime)
    override val primaryKey = PrimaryKey(id)
}

Индексы и уникальные ограничения

Вызовите .index() для обычного индекса или .uniqueIndex() для уникального индекса непосредственно в столбце. Для составных индексов используйте функцию index() у таблицы:

object Articles : Table("articles") {
    val id    = long("id").autoIncrement()
    val title = varchar("title", 300).index()
    val slug  = varchar("slug", 300).uniqueIndex()
    override val primaryKey = PrimaryKey(id)
}

Внешние ключи

Используйте .references(), чтобы объявить ограничение внешнего ключа между столбцами. Передайте связанный столбец и при необходимости действия onDelete и onUpdate:

object Posts : Table("posts") {
    val id       = long("id").autoIncrement()
    val authorId = long("author_id").references(Users.id, onDelete = ReferenceOption.CASCADE)
    val title    = varchar("title", 300)
    override val primaryKey = PrimaryKey(id)
}

Варианты IdTable

Для слоя DAO используйте типизированные таблицы идентификаторов вместо обычного Table:

  • IntIdTable("name") — автоинкрементный первичный ключ типа Int с именем id
  • LongIdTable("name") — автоинкрементный первичный ключ типа Long
  • UUIDTable("name") — первичный ключ UUID
object Users : LongIdTable("users") {
    val name  = varchar("name", 100)
    val email = varchar("email", 255).uniqueIndex()
}

Составные первичные ключи

Определите составной первичный ключ, передав несколько столбцов в PrimaryKey():

object UserRoles : Table("user_roles") {
    val userId = long("user_id").references(Users.id)
    val roleId = long("role_id").references(Roles.id)
    override val primaryKey = PrimaryKey(userId, roleId)
}

Столбцы перечислений

Сохраняйте значения перечислений Kotlin в виде строк или порядковых номеров с помощью enumerationByName() или enumeration():

enum class Status { ACTIVE, INACTIVE, BANNED }

object Users : LongIdTable("users") {
    val name   = varchar("name", 100)
    val status = enumerationByName<Status>("status", 20)
}

Применение изменений схемы

Вызовите SchemaUtils.createMissingTablesAndColumns(), чтобы добавить отсутствующие таблицы и столбцы, не удаляя существующие данные, — это безопасный способ миграции для разработки. В рабочей среде используйте инструмент миграции, например Flyway или Liquibase.

transaction {
    SchemaUtils.createMissingTablesAndColumns(Users, Posts, Orders)
}

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

Как объявить внешний ключ от Posts.authorId к Users.id в DSL таблиц Exposed?

Повторение: определение таблиц с помощью DSL таблиц

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

  • Таблицы — это object, расширяющие Table, LongIdTable и другие классы
  • Столбцы: varchar, integer, long, bool, datetime, uuid и т. д.
  • .nullable(), .default(), .uniqueIndex(), .references() изменяют столбцы
  • Составные первичные ключи: PrimaryKey(col1, col2)
  • Применяйте схему с помощью SchemaUtils.create() или createMissingTablesAndColumns()

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

Урок «Определение таблиц с DSL Table» бесплатный?

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

Чему я научусь в уроке «Определение таблиц с DSL Table»?

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

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

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

Сколько времени занимает урок «Определение таблиц с DSL Table»?

Большинство уроков 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