ORM para Kotlin: comparación y ejemplos
Al desarrollar en Kotlin, elegir el ORM (Object-Relational Mapping) adecuado es un paso clave que afecta el rendimiento, la legibilidad del código y la facilidad de mantenimiento. En este artículo compararemos tres soluciones populares: Exposed (biblioteca oficial de JetBrains), Ktorm (ORM ligera orientada a DSL) y Hibernate (el clásico pesado). Analizaremos sus puntos fuertes, características y proporcionaremos ejemplos prácticos.
1. Exposed — la elección de JetBrains
Exposed es un ORM desarrollado específicamente para Kotlin por JetBrains. Ofrece dos enfoques: DSL (type-safe) y DAO (Data Access Objects). La principal ventaja es la integración completa con el lenguaje: las tablas se describen como objetos de Kotlin y las consultas se verifican en tiempo de compilación.
Ejemplo (enfoque 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] = "Iván" it[email] = "ivan@example.com" } val result = Users.selectAll().map { "${it[Users.name]} - ${it[Users.email]}" } println(result) // [Iván - ivan@example.com] }}Características:
- Consultas type-safe (menos errores en runtime).
- No necesita reflexión (más rápido que Hibernate).
- Soporte de migraciones mediante
exposed-migration. - No requiere configuración XML ni anotaciones — todo en el código.
2. Ktorm — ligereza y flexibilidad
Ktorm es un ORM minimalista que utiliza Kotlin DSL para construir consultas SQL. A diferencia de Exposed, no genera SQL automáticamente, sino que permite escribir consultas casi como SQL puro, pero con verificación de tipos.
Ejemplo:
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() // Obtener todos los usuarios // Inserción: val user = User { name = "Pedro" email = "pedro@example.com" } database.users.add(user)}Características:
- Muy cercano a SQL — fácil optimizar consultas.
- Tamaño pequeño del JAR (~200 KB).
- Soporte de extensiones:
ktorm-jackson,ktorm-spring-support. - Requiere vinculación explícita de campos (bindTo), lo que aumenta el boilerplate.
3. Hibernate — el estándar probado
Hibernate es un ORM potente pero pesado del mundo Java. En Kotlin se usa mediante anotaciones o XML. Hibernate proporciona control total sobre el caché, la carga perezosa y la generación de esquemas. Sin embargo, debido a la reflexión y las clases proxy, pueden surgir problemas con data class (requiere open).
Ejemplo:
import javax.persistence.*
@Entity@Table(name = "users")data class User( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Int = 0, @Column(nullabl También en la biblioteca
CORS para JavaScript (Node.js): guía completa con ejemplos
ORM para TypeScript: comparación de TypeORM, Prisma y MikroORM
Geolocalización y mapas en Kotlin: bibliotecas, herramientas y ejemplos
Validación de datos en Kotlin: bibliotecas y enfoques (Kotlin, Java)
Monitoreo de aplicaciones Go: bibliotecas y herramientas