ORM para Kotlin: comparação e exemplos
Ao desenvolver em Kotlin, escolher o ORM (Object-Relational Mapping) adequado é uma etapa chave que afeta o desempenho, a legibilidade do código e a facilidade de manutenção. Neste artigo, compararemos três soluções populares: Exposed (biblioteca oficial da JetBrains), Ktorm (ORM leve e orientada a DSL) e Hibernate (o clássico pesado). Analisaremos seus pontos fortes, características e forneceremos exemplos práticos.
1. Exposed — a escolha da JetBrains
Exposed é um ORM desenvolvido especificamente para Kotlin pela empresa JetBrains. Ele oferece duas abordagens: DSL (type-safe) e DAO (Data Access Objects). A principal vantagem é a integração total com a linguagem: as tabelas são descritas como objetos Kotlin e as consultas são verificadas em tempo de compilação.
Exemplo (abordagem DSL):
import org.jetbrains.exposed.sql.*import org.jetbrains.exposed.sql.transactions.transaction
object Users : Table() { val id = integer("id").autoIncrement() val name = varchar("name", 50) val email = varchar("email", 100).uniqueIndex() override val primaryKey = PrimaryKey(id)}
fun main() { Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") transaction { SchemaUtils.create(Users) Users.insert { it[name] = "Иван" it[email] = "ivan@example.com" } val result = Users.selectAll().map { "${it[Users.name]} - ${it[Users.email]}" } println(result) // [Иван - ivan@example.com] }}Características:
- Consultas type-safe (menos erros em runtime).
- Não requer reflexão (mais rápido que o Hibernate).
- Suporte a migrações via
exposed-migration. - Não requer configuração de XML ou anotações — tudo no código.
2. Ktorm — leveza e flexibilidade
Ktorm é um ORM minimalista que usa Kotlin DSL para construir consultas SQL. Ao contrário do Exposed, ele não gera SQL automaticamente, mas permite escrever consultas quase como SQL puro, porém com verificação de tipos.
Exemplo:
import me.liuwj.ktorm.database.Databaseimport me.liuwj.ktorm.entity.*import me.liuwj.ktorm.schema.*
interface User : Entity<User> { companion object : Entity.Factory<User>() val id: Int val name: String val email: String}
object Users : Table<User>("users") { val id = int("id").primaryKey().bindTo { it.id } val name = varchar("name").bindTo { it.name } val email = varchar("email").bindTo { it.email }}
fun main() { val database = Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") database.sequenceOf(Users).toList() // Obter todos os usuários // Inserção: val user = User { name = "Петр" email = "petr@example.com" } database.users.add(user)}Características:
- Máxima proximidade com SQL — fácil otimizar consultas.
- Tamanho pequeno do JAR (~200 KB).
- Suporte a extensões:
ktorm-jackson,ktorm-spring-support. - Requer vinculação explícita de campos (bindTo), o que aumenta o boilerplate.
3. Hibernate — o padrão consolidado
Hibernate é um ORM poderoso, porém pesado, do mundo Java. Em Kotlin, é usado através de anotações ou XML. O Hibernate oferece controle total sobre cache, carregamento lazy e geração de esquema. No entanto, devido à reflexão e classes proxy, podem surgir problemas com data class (requer open).
Exemplo:
import javax.persistence.*
@Entity@Table(name = "users")data class User( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Int = 0, @Column(nullabl Também na biblioteca
Mongoose para JavaScript (Node.js): guia completo com exemplos
Trabalhando com Apache Kafka em C++: biblioteca librdkafka e exemplos práticos
Trabalho com YAML em TypeScript: parsing, geração e validação de dados
Event Bus e padrão Observer em Go (Golang): implementação e exemplos