Introducción: Por qué Kotlin es una excelente opción para trabajar con bases de datos
Kotlin, siendo un lenguaje de programación moderno y conciso, proporciona a los desarrolladores herramientas potentes para interactuar con diversas bases de datos. Gracias a su total compatibilidad con Java y su propio ecosistema de bibliotecas, Kotlin permite escribir código seguro, expresivo y eficiente para trabajar tanto con almacenes relacionales (SQL) como orientados a documentos (NoSQL).
En este artículo, analizaremos con ejemplos prácticos la conexión y ejecución de operaciones CRUD (Create, Read, Update, Delete) para dos sistemas de gestión de bases de datos populares: PostgreSQL (relacional) y MongoDB (documental). Aprenderá a configurar el proyecto, utilizar bibliotecas modernas (Exposed para SQL y KMongo para MongoDB) y escribir código limpio teniendo en cuenta las características de Kotlin.
1. Trabajo con PostgreSQL en Kotlin: usando la biblioteca Exposed
Para trabajar con bases de datos relacionales en Kotlin, existen varios enfoques. Consideraremos la biblioteca Exposed, un envoltorio ORM ligero escrito en Kotlin que proporciona un DSL (Domain-Specific Language) con seguridad de tipos para formar consultas SQL.
1.1. Adición de dependencias
Agregue las siguientes dependencias al archivo build.gradle.kts:
dependencies { implementation("org.jetbrains.exposed:exposed-core:0.41.1") implementation("org.jetbrains.exposed:exposed-dao:0.41.1") implementation("org.jetbrains.exposed:exposed-jdbc:0.41.1") implementation("org.postgresql:postgresql:42.6.0") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")}1.2. Creación de tabla y conexión a la BD
Definamos la entidad "Usuario" y la tabla correspondiente en el código:
import org.jetbrains.exposed.sql.*import org.jetbrains.exposed.sql.transactions.transactionimport org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
// Definimos la tablaobject Users : Table() { val id = integer("id").autoIncrement() val name = varchar("name", 255) val email = varchar("email", 255).uniqueIndex()
override val primaryKey = PrimaryKey(id)}
// Data class para el usuariodata class User(val id: Int, val name: String, val email: String)
fun main() { // Conexión a la base de datos Database.connect( url = "jdbc:postgresql://localhost:5432/mydb", driver = "org.postgresql.Driver", user = "postgres", password = "password" )
// Creación de la tabla (si no existe) transaction { SchemaUtils.create(Users) }}1.3. Operaciones CRUD
Ahora implementemos las operaciones básicas de creación, lectura, actualización y eliminación de registros:
fun createUser(name: String, email: String): User { return transaction { val insertId = Users.insert { it[Users.name] = name it[Users.email] = email } get Users.id
User( id = insertId, name = name, email = email ) }}
fun readUserById(id: Int): User? { return transaction { Users.selectAll().where { Users.id eq id } .singleOrNull() ?.let { row -> User( id = row[Users.id], name = row[Users.name], email = row[Users.email] ) } }}
fun updateUserEmail(id: Int, newEmail: String) { transaction { Users.update({ Users.id eq id }) { it[email] = newEmail } }}
fun deleteUser(id: Int) { transaction { Users.deleteWhere { Users.id eq id } }}Gracias a Exposed, el código Kotlin resulta conciso y seguro en cuanto a tipos. Los errores en nombres de columnas o tablas se detectan