ORM для Kotlin: сравнение и примеры
При разработке приложений на Kotlin работа с базами данных — одна из ключевых задач. Вместо написания сырых SQL-запросов разработчики всё чаще используют ORM (Object-Relational Mapping) — инструменты, которые автоматизируют преобразование данных между объектной моделью и реляционными таблицами. В этой статье мы рассмотрим три популярных ORM для Kotlin: Exposed, Room и Ktorm. Сравним их архитектуру, производительность, удобство использования и приведём практические примеры кода.
1. Exposed — лёгкая DSL-библиотека от JetBrains
Exposed — это библиотека, разработанная создателями Kotlin. Она не является полноценным ORM в классическом понимании (как Hibernate), а предоставляет два подхода: DSL (Domain Specific Language) для написания запросов в стиле Kotlin и DAO (Data Access Objects) для работы с объектами. Exposed работает поверх JDBC и поддерживает PostgreSQL, MySQL, H2, SQLite и другие.
Пример кода с Exposed (DSL)
// Подключение к БД
Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver")
// Определение таблицы
object Users : Table("users") {
val id = integer("id").autoIncrement()
val name = varchar("name", 50)
val age = integer("age")
override val primaryKey = PrimaryKey(id)
}
// Вставка и выборка
transaction {
SchemaUtils.create(Users)
Users.insert {
it[name] = "Alice"
it[age] = 30
}
Users.selectAll().forEach {
println("${it[Users.name]}: ${it[Users.age]}")
}
}
Плюсы и минусы Exposed
- Плюсы: лёгкий вес, полный контроль над SQL, хорошая интеграция с Kotlin Coroutines, активное сообщество.
- Минусы: отсутствие автоматической генерации схемы (нужно создавать вручную), нет встроенной поддержки миграций (требуется Flyway или Liquibase).
2. Room — официальный ORM для Android от Google
Room — это библиотека, входящая в состав Android Jetpack. Она предоставляет уровень абстракции над SQLite и автоматически генерирует код для доступа к данным. Room использует аннотации и компиляцию на этапе сборки (KAPT или KSP), что обеспечивает высокую производительность и безопасность типов.
Пример кода с Room
// Сущность
@Entity(tableName = "users")
data class User(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
val name: String,
val age: Int
)
// DAO
@Dao
interface UserDao {
@Query("SELECT * FROM users")
suspend fun getAll(): List<User>
@Insert
suspend fun insert(user: User)
}
// База данных
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
Плюсы и минусы Room
- Плюсы: полная интеграция с Android, поддержка Flow и LiveData, автоматическая генерация кода, встроенные миграции.
- Минусы: привязан к платформе Android (не подходит для серверных или десктопных приложений), более тяжёлый по сравнению с Exposed.
3. Ktorm — функциональный ORM для Kotlin
Ktorm — это современная ORM-библиотека, которая предлагает функциональный стиль работы с базами данных. Она не использует аннотации и рефлексию, а полагается на Kotlin DSL и расширения. Ktorm поддерживает множество СУБД (MySQL, PostgreSQL, Oracle, SQLite и др.) и может работать как с JDBC, так и с SQL-диалектами.
Пример кода с Ktorm
// Подключение и определение таблицы
val database = Database.connect("jdbc:mysql://localhost/mydb", user = "root", password = "pass")
object Users : Table<Nothing>("users") {
val id = int("id").primaryKey()
val name = varchar("name")
val age = int("age")
}
// Вставка и выборка
database.insert(Users) {
set(it.name, "Bob")
set(it.age, 25)
}
database.from(Users).select().forEach { row ->
println("${row[Users.name]}: ${row[Users.age]}")
}
Плюсы и минусы Ktorm
- Плюсы: гибкость, отсутствие рефлексии, поддержка расширений (например, для работы с JSON), хорошая документация.
- Минусы: меньшая популярность по сравнению с Exposed, сложнее в освоении для новичков.