Ejecutar consultas
Lea filas en case classes
Ejecutar consultas es una lección gratuita de Scala for Backend Engineering & Functional Programming en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Scala for Backend Engineering & Functional Programming, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Scala for Backend Engineering & Functional Programming incluye 4 lecciones en total.
El interpolador sql
El interpolador de cadenas sql de Doobie es la base de las consultas. Analiza el SQL y convierte los valores de Scala insertados en parámetros vinculados de forma segura.
Los valores interpolados se convierten en marcadores JDBC ?, por lo que no hay inyección SQL ni es necesario configurar manualmente un PreparedStatement.
import doobie.implicits._
val minAge = 18
val frag = sql"select name from users where age >= $minAge"De Fragment a Query
Una expresión sql"..." es un Fragment. Para ejecutarla como lectura, llame a .query[A] y elija el tipo de fila A.
Doobie usa una typeclass Read[A] para asignar las columnas del resultado a A, y admite tipos primitivos, tuplas y clases de caso.
case class User(name: String, age: Int)
val q: Query0[User] =
sql"select name, age from users".query[User]unique, option y to
Un Query0[A] ofrece distintos acumuladores. .unique espera exactamente una fila, .option espera cero o una y .to[List] recopila todas las filas.
Cada uno devuelve un ConnectionIO que después ejecutará con .transact.
val one: ConnectionIO[User] = q.unique
val maybe: ConnectionIO[Option[User]] = q.option
val all: ConnectionIO[List[User]] = q.to[List]Asignación de filas a clases de caso
Doobie deriva automáticamente instancias de Read para clases de caso cuando cada campo tiene una correspondencia de columna. El orden de las columnas debe coincidir con la lista de selección.
Esto permite seleccionar directamente en tipos de dominio completos sin escribir código repetitivo para analizar las filas.
case class Account(id: Long, email: String, active: Boolean)
val accounts =
sql"select id, email, active from accounts"
.query[Account].to[Vector]Consultas parametrizadas
Cada valor de Scala interpolado se vincula como parámetro mediante su instancia de Put. Puede interpolar tantos valores como quiera, incluso en posiciones distintas.
Como se vinculan en lugar de concatenarse, los tipos se comprueban y la inyección resulta imposible.
def findByEmail(email: String): ConnectionIO[Option[Account]] =
sql"select id, email, active from accounts where email = $email"
.query[Account].optionTransmisión de resultados grandes
Para conjuntos de resultados grandes, use .stream para obtener un Stream[ConnectionIO, A] de fs2. Las filas se obtienen de forma diferida mediante un cursor del servidor, lo que mantiene acotado el uso de memoria.
Combínelo con los combinadores de fs2 para procesar millones de filas de forma incremental.
import fs2.Stream
val s: Stream[ConnectionIO, Account] =
sql"select id, email, active from accounts"
.query[Account].streamControl del tamaño de lectura
En algunos drivers, el tamaño de lectura predeterminado del cursor puede cargarlo todo de una vez. .streamWithChunkSize(n) establece el tamaño de lectura de JDBC para que el cursor obtenga n filas en cada ida y vuelta.
Ajustarlo permite equilibrar las idas y vueltas con el uso de memoria.
val s =
sql"select id, email, active from accounts"
.query[Account]
.streamWithChunkSize(512)Columnas opcionales y nulabilidad
Las columnas que admiten valores nulos se asignan a Option[A] en el tipo de fila. Si una columna puede ser NULL, debe leerla como un Option; de lo contrario, Doobie lanzará una excepción al encontrar un valor nulo.
Esto hace que la nulabilidad sea explícita y segura en cuanto a tipos en los límites del sistema.
case class Person(id: Long, nickname: Option[String])
val ps =
sql"select id, nickname from people".query[Person].to[List]Construcción de SQL con Fragments
Los valores Fragment se componen con ++, lo que permite ensamblar consultas a partir de piezas y mantener los parámetros vinculados.
El interpolador fr construye un fragmento con un espacio final, lo que resulta práctico para unir cláusulas.
val base = fr"select id, email, active from accounts"
val where = fr"where active = $${true}"
val q = (base ++ where).query[Account]Cláusulas WHERE dinámicas
Los helpers Fragments de Doobie construyen cláusulas condicionales. Fragments.whereAndOpt combina filtros opcionales y solo emite los que están presentes.
Esta es la forma idiomática de construir consultas de búsqueda dinámicas y seguras.
import doobie.util.fragments._
val emailOpt: Option[String] = Some("a@b.com")
val filter = whereAndOpt(emailOpt.map(e => fr"email = $e"))
val q = (fr"select id, email, active from accounts" ++ filter)Comprobación de consultas en tiempo de compilación
El análisis check de Doobie ejecuta una consulta contra el esquema de la base de datos para verificar que los tipos y la cantidad de columnas coincidan con los tipos de Scala.
Usado en las pruebas, detecta cambios incompatibles en el esquema antes de que lleguen a producción.
import doobie.scalatest._
// inside a spec mixing in IOChecker
check(sql"select id, email, active from accounts".query[Account])Comprobación rápida
Elija el acumulador adecuado.
Resumen
El interpolador sql construye Fragments parametrizados; .query[A] los convierte en un Query0[A] asignado mediante Read[A].
Elija .unique, .option, .to[List] o .stream para acumular filas. Use Fragments para las cláusulas dinámicas y check para validar el esquema.
Preguntas frecuentes
¿La lección «Ejecutar consultas» es gratis?
Sí — el texto completo de «Ejecutar consultas» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Scala for Backend Engineering & Functional Programming, actualiza a CoddyKit PRO. El curso de Scala for Backend Engineering & Functional Programming incluye 4 lecciones en total.
¿Qué aprenderé en «Ejecutar consultas»?
Lea filas en case classes Practicas Scala for Backend Engineering & Functional Programming con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Scala for Backend Engineering & Functional Programming?
No se requiere experiencia previa. Scala for Backend Engineering & Functional Programming en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «Ejecutar consultas»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Scala for Backend Engineering & Functional Programming?
Sí. Cada lección de Scala for Backend Engineering & Functional Programming incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.