Einfügen und aktualisieren
Schreiben Sie Daten auf funktionale Weise.
Einfügen und aktualisieren ist eine kostenlose Scala for Backend Engineering & Functional Programming-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Scala for Backend Engineering & Functional Programming-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Scala for Backend Engineering & Functional Programming-Kurs umfasst insgesamt 4 Lektionen.
Teile dieser Lektion wurden noch nicht übersetzt und werden auf Englisch angezeigt.
Update0 for Writes
Writes use the same sql interpolator, but you call .update to get an Update0 instead of .query.
Running .run on an Update0 returns a ConnectionIO[Int]: the number of affected rows.
import doobie.implicits._
def insert(name: String, age: Int): ConnectionIO[Int] =
sql"insert into users (name, age) values ($name, $age)".update.runAffected Row Counts
The Int from .run is the JDBC update count. For an UPDATE or DELETE it tells you how many rows matched.
You can branch on it to detect, for example, an update that matched no rows.
def deactivate(id: Long): ConnectionIO[Int] =
sql"update users set active = false where id = $id".update.runReturning Generated Keys
To get an auto-generated primary key, use .withUniqueGeneratedKeys, naming the columns the database returns.
This runs the insert and reads back the generated values in one round trip.
def insertReturningId(name: String, age: Int): ConnectionIO[Long] =
sql"insert into users (name, age) values ($name, $age)"
.update
.withUniqueGeneratedKeys[Long]("id")Returning a Whole Row
You can return several generated or defaulted columns at once by reading them into a tuple or case class.
This is great for capturing server-side defaults like timestamps right after insert.
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")The Update Class for Batches
Update[A] is a prepared, parameterized statement you can run many times. You define the SQL once with ? placeholders and supply values of type A.
It is built from a SQL string plus a Write[A] instance.
val ins: Update[(String, Int)] =
Update[(String, Int)]("insert into users (name, age) values (?, ?)")Efficient Batch Inserts
updateMany sends a whole collection in one JDBC batch, far faster than looping single inserts.
It returns the total number of affected rows. Use it whenever you load many rows at once.
val rows = List(("Ada", 36), ("Linus", 54))
val batch: ConnectionIO[Int] = ins.updateMany(rows)Batch Insert with Keys
Update can also stream generated keys for a batch via updateManyWithGeneratedKeys, giving back a row per inserted record.
This combines bulk loading with reading back assigned identifiers.
import fs2.Stream
val keyed: Stream[ConnectionIO, Long] =
ins.updateManyWithGeneratedKeys[Long]("id")(rows)Upserts with ON CONFLICT
Database-specific upserts work fine through Doobie. On PostgreSQL you write insert ... on conflict ... do update as normal SQL.
Doobie just binds your parameters; the upsert semantics belong to the database.
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.runWrite Instances and Defaults
Parameters are encoded with the Write[A] typeclass, derived for primitives, tuples, and case classes. Each field needs a Put instance.
If you omit a column from the insert, the database applies its DEFAULT, which is how generated timestamps appear.
case class NewUser(name: String, age: Int)
val mk = Update[NewUser](
"insert into users (name, age) values (?, ?)"
)Custom Column Mappings with Meta
To persist a custom type, define a Meta[A] by mapping it to an existing column type with imap (or timap).
A Meta provides both reading and writing, so the type works in queries and updates alike.
import doobie.util.meta.Meta
case class UserId(value: Long)
implicit val uidMeta: Meta[UserId] =
Meta[Long].imap(UserId.apply)(_.value)Deletes Are Updates Too
DELETE statements also use .update.run and return the count of removed rows.
Treating inserts, updates, and deletes uniformly as Update0 keeps the API small and composable.
def purgeInactive: ConnectionIO[Int] =
sql"delete from users where active = false".update.runQuick Check
Pick the most efficient approach.
Recap
Writes use .update to produce an Update0; .run returns affected rows and .withUniqueGeneratedKeys reads back generated values.
For bulk work, Update[A].updateMany batches efficiently. Custom types get Meta instances, and upserts are just normal database SQL bound by Doobie.
Häufig gestellte Fragen
Ist die Lektion „Einfügen und aktualisieren“ kostenlos?
Ja — der vollständige Text von „Einfügen und aktualisieren“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Scala for Backend Engineering & Functional Programming-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Scala for Backend Engineering & Functional Programming-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Einfügen und aktualisieren“?
Schreiben Sie Daten auf funktionale Weise. Du übst Scala for Backend Engineering & Functional Programming mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Scala for Backend Engineering & Functional Programming zu starten?
Keine Vorkenntnisse erforderlich. Scala for Backend Engineering & Functional Programming auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Einfügen und aktualisieren“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Scala for Backend Engineering & Functional Programming-Lektion Code schreiben und ausführen?
Ja. Jede Scala for Backend Engineering & Functional Programming-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Mit einem Transactor verbinden
- Abfragen ausführen
- Einfügen und aktualisieren
- Transaktionen kombinieren