Introducción al trabajo con bases de datos en Kotlin
\n\nKotlin es un lenguaje moderno de tipado estático que se ejecuta en la JVM, que está ganando popularidad rápidamente gracias a su concisión y seguridad. Una de las habilidades clave para cualquier desarrollador es la capacidad de interactuar con bases de datos. En este artículo, veremos cómo conectarse y realizar operaciones básicas (CRUD) con los dos tipos de BD más populares: la relacional PostgreSQL y la orientada a documentos MongoDB.
\n\nUsaremos bibliotecas modernas, máximamente adaptadas al Kotlin idiomático:
\n- \n
- Exposed — framework ORM de JetBrains para bases de datos SQL (PostgreSQL, MySQL, etc.). \n
- KMongo — cliente ODM reactivo para MongoDB, construido sobre corrutinas. \n
El artículo está dirigido a principiantes: analizaremos la configuración del proyecto, la conexión a la BD y ejemplos simples de inserción, lectura, actualización y eliminación de datos.
\n\n1. Configuración del proyecto y adición de dependencias
\n\nPara empezar, crea un nuevo proyecto Kotlin (por ejemplo, a través de IntelliJ IDEA con Gradle o Maven). Añade las dependencias necesarias en el archivo build.gradle.kts.
Dependencias Gradle para PostgreSQL (Exposed)
\ndependencies {\n // Exposed\n implementation("org.jetbrains.exposed:exposed-core:0.44.1")\n implementation("org.jetbrains.exposed:exposed-dao:0.44.1")\n implementation("org.jetbrains.exposed:exposed-jdbc:0.44.1")\n\n // Driver PostgreSQL\n implementation("org.postgresql:postgresql:42.7.1")\n\n // Pool de conexiones (HikariCP)\n implementation("com.zaxxer:HikariCP:5.1.0")\n}\n\nDependencias Gradle para MongoDB (KMongo)
\ndependencies {\n // KMongo (con corrutinas)\n implementation("org.litote.kmongo:kmongo-coroutine:4.11.0")\n\n // Ktor Client (si se necesita driver reactivo)\n implementation("org.litote.kmongo:kmongo-async:4.11.0")\n}\n\nDespués de sincronizar el proyecto, se puede proceder a la conexión.
\n\n2. Trabajo con PostgreSQL a través de Exposed
\n\nExposed proporciona dos enfoques: DSL (consultas SQL con seguridad de tipos) y DAO (mapeo objeto-relacional). Veremos DAO, que es más intuitivo para principiantes.
\n\nConexión a la base de datos
\nimport org.jetbrains.exposed.sql.Database\nimport org.jetbrains.exposed.sql.transactions.transaction\nimport com.zaxxer.hikari.HikariConfig\nimport com.zaxxer.hikari.HikariDataSource\n\nfun connectToPostgres() {\n val config = HikariConfig().apply {\n jdbcUrl = "jdbc:postgresql://localhost:5432/mydb"\n driverClassName = "org.postgresql.Driver"\n username = "user"\n password = "password"\n maximumPoolSize = 10\n }\n val dataSource = HikariDataSource(config)\n Database.connect(dataSource)\n println("¡Conexión a PostgreSQL establecida!")\n}\n\nDefinición de tabla y entidad
\nimport org.jetbrains.exposed.dao.id.IntIdTable\nimport org.jetbrains.exposed.dao.IntEntity\nimport org.jetbrains.exposed.dao.IntEntityClass\n\n// Definimos la tabla\nobject UsersTable : IntIdTable("users") {\n val name = varchar("name", 100)\n val email = varchar("email", 255).uniqueIndex()\n val age = integer("age").default(18)\n}\n\n// Definimos la Entity (DAO)\nclass UserEntity(id: EntityID<Int>) : IntEntity(id) {\n companion object : IntEntityClass<UserEntity>(UsersTable)\n\n var name by UsersTable.name\n var email by UsersTable.email\n var age by UsersTable.age\n}\n\nOperaciones CRUD
\nfun performCRUD() {\n transaction {\n // Creación de la tabla (si no existe)\n SchemaUtils.create(UsersTable)\n\n // INSERT\n val newUser = UserEntity.new {\n name = "Iván Petrov"\n email = "ivan@example.com"\n age = 25\n }\n println("Usuario creado