Inserciones y actualizaciones
Escriba datos de forma funcional
Inserciones y actualizaciones es una lección gratuita de Scala for Backend Engineering & Functional Programming en CoddyKit. Esta es la lección 3 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.
Update0 para escrituras
Las operaciones de escritura utilizan el mismo interpolador sql, pero se llama a .update para obtener un Update0 en lugar de .query.
Ejecutar .run sobre un Update0 devuelve un ConnectionIO[Int]: el número de filas afectadas.
import doobie.implicits._
def insert(name: String, age: Int): ConnectionIO[Int] =
sql"insert into users (name, age) values ($name, $age)".update.runRecuentos de filas afectadas
El Int de .run es el recuento de actualizaciones de JDBC. En una operación UPDATE o DELETE indica cuántas filas coincidieron.
Puede usarlo para tomar decisiones, por ejemplo, para detectar una actualización que no coincidió con ninguna fila.
def deactivate(id: Long): ConnectionIO[Int] =
sql"update users set active = false where id = $id".update.runDevolver claves generadas
Para obtener una clave primaria generada automáticamente, use .withUniqueGeneratedKeys e indique las columnas que devuelve la base de datos.
Esto ejecuta la inserción y recupera los valores generados en un solo viaje de ida y vuelta.
def insertReturningId(name: String, age: Int): ConnectionIO[Long] =
sql"insert into users (name, age) values ($name, $age)"
.update
.withUniqueGeneratedKeys[Long]("id")Devolver una fila completa
Puede devolver varias columnas generadas o con valores predeterminados a la vez leyéndolas en una tupla o una clase de caso.
Esto resulta muy útil para capturar valores predeterminados del servidor, como marcas de tiempo, justo después de insertar.
case class User(id: Long, name: String, createdAt: java.time.Instant)
def create(name: String): ConnectionIO[User] =
sql"insert into users (name) values ($name)"
.update
.withUniqueGeneratedKeys[User]("id", "name", "created_at")La clase Update para operaciones por lotes
Update[A] es una sentencia preparada y parametrizada que puede ejecutar muchas veces. Define el SQL una sola vez con marcadores ? y proporciona valores de tipo A.
Se construye a partir de una cadena SQL y una instancia de Write[A].
val ins: Update[(String, Int)] =
Update[(String, Int)]("insert into users (name, age) values (?, ?)")Inserciones por lotes eficientes
updateMany envía una colección completa en un solo lote de JDBC, mucho más rápido que repetir inserciones individuales.
Devuelve el número total de filas afectadas. Úselo siempre que cargue muchas filas a la vez.
val rows = List(("Ada", 36), ("Linus", 54))
val batch: ConnectionIO[Int] = ins.updateMany(rows)Inserción por lotes con claves
Update también puede transmitir claves generadas para un lote mediante updateManyWithGeneratedKeys, devolviendo una fila por cada registro insertado.
Esto combina la carga masiva con la recuperación de los identificadores asignados.
import fs2.Stream
val keyed: Stream[ConnectionIO, Long] =
ins.updateManyWithGeneratedKeys[Long]("id")(rows)Upserts con ON CONFLICT
Los upserts específicos de cada base de datos funcionan perfectamente con Doobie. En PostgreSQL, escriba insert ... on conflict ... do update como SQL normal.
Doobie se limita a vincular sus parámetros; la semántica del upsert pertenece a la base de datos.
def upsert(email: String, name: String): ConnectionIO[Int] =
sql"""insert into accounts (email, name) values ($email, $name)
on conflict (email) do update set name = excluded.name"""
.update.runInstancias de Write y valores predeterminados
Los parámetros se codifican con la typeclass Write[A], derivada para tipos primitivos, tuplas y clases de caso. Cada campo necesita una instancia de Put.
Si omite una columna en la inserción, la base de datos aplica su valor DEFAULT, que es la forma en que aparecen las marcas de tiempo generadas.
case class NewUser(name: String, age: Int)
val mk = Update[NewUser](
"insert into users (name, age) values (?, ?)"
)Mapeos de columnas personalizados con Meta
Para conservar un tipo personalizado, defina un Meta[A] asignándolo a un tipo de columna existente mediante imap (o timap).
Un Meta proporciona tanto lectura como escritura, por lo que el tipo funciona por igual en consultas y actualizaciones.
import doobie.util.meta.Meta
case class UserId(value: Long)
implicit val uidMeta: Meta[UserId] =
Meta[Long].imap(UserId.apply)(_.value)Las eliminaciones también son actualizaciones
Las sentencias DELETE también utilizan .update.run y devuelven el recuento de filas eliminadas.
Tratar de forma uniforme las inserciones, actualizaciones y eliminaciones como Update0 mantiene una API pequeña y componible.
def purgeInactive: ConnectionIO[Int] =
sql"delete from users where active = false".update.runComprobación rápida
Elija el enfoque más eficiente.
Resumen
Las operaciones de escritura utilizan .update para producir un Update0; .run devuelve las filas afectadas y .withUniqueGeneratedKeys recupera los valores generados.
Para operaciones masivas, Update[A].updateMany realiza lotes de forma eficiente. Los tipos personalizados obtienen instancias de Meta, y los upserts son simplemente SQL normal de la base de datos, con los parámetros vinculados por Doobie.
Preguntas frecuentes
¿La lección «Inserciones y actualizaciones» es gratis?
Sí — el texto completo de «Inserciones y actualizaciones» 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 «Inserciones y actualizaciones»?
Escriba datos de forma funcional 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 3 de 4.
¿Cuánto tiempo toma la lección «Inserciones y actualizaciones»?
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.
Todas las lecciones de este curso
- Conectar con un transactor
- Ejecutar consultas
- Inserciones y actualizaciones
- Componer transacciones