jOOQ в Kotlin используют как типизированный способ писать SQL-запросы из кода. Вы не собираете строки руками, а работаете через DSL: selectFrom, where, fetch, insertInto. Это удобно, когда в проекте важен реальный SQL, но хочется подсказок IDE и проверки структуры
Минимальная идея:
val users = dsl
.selectFrom(USERS)
.where(USERS.ACTIVE.eq(true))
.fetch()
Здесь dsl — это DSLContext, а USERS — сгенерированная jOOQ-таблица
Что нужно подключить
Обычно в проекте есть:
- JDBC-драйвер вашей базы;
- jOOQ;
- генерация классов по схеме базы;
DSLContext, через который выполняются запросы.
Упрощенная зависимость для Gradle:
dependencies {
implementation("org.jooq:jooq:3.20.14")
runtimeOnly("org.postgresql:postgresql:42.7.7")
}
Версии проверяйте под ваш проект. На 1 июня 2026 года в Maven Repository видна ветка 3.20.x, а в официальном manual уже есть переключатель на более новые ветки документации. JDBC-драйвер зависит от базы: PostgreSQL, MySQL, SQLite или другой
Пример запроса
Если классы уже сгенерированы, чтение данных выглядит так:
fun activeUsers(dsl: DSLContext): List<String> {
return dsl
.select(USERS.NAME)
.from(USERS)
.where(USERS.ACTIVE.eq(true))
.fetch(USERS.NAME)
}
Kotlin здесь дает лаконичный синтаксис, а jOOQ оставляет запрос похожим на SQL
Где взять USERS
USERS обычно появляется после code generation. jOOQ читает схему базы и создает Java/Kotlin-доступные классы таблиц. Поэтому рабочий порядок такой: сначала база или миграции, потом генерация, потом код запросов
Если вы просто вставили пример и IDE не видит USERS, это нормально: у вас еще нет сгенерированной модели. Для настоящего проекта настройте генератор под вашу базу и package
Пример вставки
fun createUser(dsl: DSLContext, name: String) {
dsl.insertInto(USERS)
.set(USERS.NAME, name)
.set(USERS.ACTIVE, true)
.execute()
}
Метод execute() возвращает количество затронутых строк. Для первой проверки можно вывести результат в лог
Когда jOOQ хорош
jOOQ особенно удобен, если:
- вам нужен контроль над SQL;
- в проекте сложные запросы;
- ORM кажется слишком магической;
- хочется автодополнение по таблицам и полям;
- команда умеет читать SQL.
Если приложение совсем маленькое, jOOQ может быть избыточным. Для пары простых таблиц иногда хватит Exposed, JDBC или Spring Data
Как проверить
- Проверьте, что подключение к базе работает.
- Убедитесь, что jOOQ сгенерировал классы таблиц.
- Выполните простой
select. - Сравните результат с тем же запросом в SQL-клиенте.
Если USERS не находится, проблема почти наверняка в генерации классов или package, а не в Kotlin
Частые ошибки
Пытаться писать jOOQ без генерации
Можно использовать jOOQ и без генерации, но основная сила библиотеки раскрывается именно со сгенерированными таблицами
Смешивать бизнес-логику и SQL
Запросы лучше держать в repository-слое, а не разбрасывать по контроллерам
Ожидать, что jOOQ заменяет понимание SQL
jOOQ не отменяет SQL. Он помогает писать его безопаснее из Kotlin-кода
Не закрывать соединения
jOOQ работает поверх JDBC. Следите, кто управляет подключением: HikariCP, Spring, Ktor-плагин или ваш код. Сам DSL не освобождает вас от нормального жизненного цикла соединений
Что почитать дальше по Kotlin
Если нужен общий маршрут по теме, откройте рубрику Kotlin. Для соседних задач пригодятся эти разборы:
- Inline в Kotlin: что это и когда использовать
- Coroutines в Kotlin: первый async-пример
- Kotlin Android: первый экран без перегруза
- Kotlin serialization: как настроить JSON на простом примере



