Introdução: Por que Kotlin é uma excelente escolha para trabalhar com bancos de dados
Kotlin, sendo uma linguagem de programação moderna e concisa, oferece aos desenvolvedores ferramentas poderosas para interagir com diversos bancos de dados. Graças à total compatibilidade com Java e ao seu próprio ecossistema de bibliotecas, Kotlin permite escrever código seguro, expressivo e performático para trabalhar tanto com armazenamentos relacionais (SQL) quanto orientados a documentos (NoSQL).
Neste artigo, abordaremos com exemplos práticos a conexão e a execução de operações CRUD (Create, Read, Update, Delete) para dois sistemas populares de gerenciamento de bancos de dados: PostgreSQL (relacional) e MongoDB (documental). Você aprenderá como configurar o projeto, usar bibliotecas modernas (Exposed para SQL e KMongo para MongoDB) e escrever código limpo considerando as particularidades do Kotlin.
1. Trabalhando com PostgreSQL em Kotlin: usando a biblioteca Exposed
Para trabalhar com bancos de dados relacionais em Kotlin, existem várias abordagens. Vamos considerar a biblioteca Exposed — uma camada ORM leve escrita em Kotlin, que fornece um DSL (Domain-Specific Language) type-safe para formular consultas SQL.
1.1. Adicionando dependências
Adicione as seguintes dependências ao arquivo 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. Criando a tabela e conectando ao banco de dados
Vamos definir a entidade "Usuário" e a tabela correspondente no código:
import org.jetbrains.exposed.sql.*import org.jetbrains.exposed.sql.transactions.transactionimport org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
// Definindo a tabelaobject 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 o usuáriodata class User(val id: Int, val name: String, val email: String)
fun main() { // Conexão ao banco de dados Database.connect( url = "jdbc:postgresql://localhost:5432/mydb", driver = "org.postgresql.Driver", user = "postgres", password = "password" )
// Criando a tabela (se não existir) transaction { SchemaUtils.create(Users) }}1.3. Operações CRUD
Agora vamos implementar as operações básicas de criação, leitura, atualização e exclusão 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 } }}Graças ao Exposed, o código Kotlin fica conciso e type-safe. Erros em nomes de colunas ou tabelas são detectados em tempo de compilação.