Scala voor backend-engineering en functioneel programmeren · Les

Inserts en updates

Schrijf gegevens functioneel.

Les 3 van 413 stappen

Inserts en updates is een gratis Scala voor backend-engineering en functioneel programmeren-les op CoddyKit. Dit is les 3 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Scala voor backend-engineering en functioneel programmeren. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Scala voor backend-engineering en functioneel programmeren bevat in totaal 4 lessen.

Update0 voor schrijfbewerkingen

Schrijfbewerkingen gebruiken dezelfde sql-interpolator, maar je roept .update aan om een Update0 te krijgen in plaats van .query.

Als je .run uitvoert op een Update0, krijg je een ConnectionIO[Int] terug: het aantal gewijzigde rijen.

import doobie.implicits._

def insert(name: String, age: Int): ConnectionIO[Int] =
  sql"insert into users (name, age) values ($name, $age)".update.run

Aantal gewijzigde rijen

De Int van .run is het JDBC-updateaantal. Bij een UPDATE of DELETE geeft dit aan hoeveel rijen overeenkwamen.

Je kunt op basis hiervan vertakken om bijvoorbeeld vast te stellen dat een update geen rijen heeft gevonden.

def deactivate(id: Long): ConnectionIO[Int] =
  sql"update users set active = false where id = $id".update.run

Automatisch gegenereerde sleutels teruggeven

Gebruik .withUniqueGeneratedKeys om een automatisch gegenereerde primaire sleutel op te halen en geef daarbij de kolommen op die de database teruggeeft.

Hiermee wordt de insert uitgevoerd en worden de gegenereerde waarden in één rondreis teruggelezen.

def insertReturningId(name: String, age: Int): ConnectionIO[Long] =
  sql"insert into users (name, age) values ($name, $age)"
    .update
    .withUniqueGeneratedKeys[Long]("id")

Een volledige rij teruggeven

Je kunt meerdere gegenereerde of standaardwaarden tegelijk teruggeven door ze in een tuple of case class te lezen.

Dit is handig om standaardwaarden aan de serverzijde, zoals tijdstempels, direct na een insert vast te leggen.

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")

De Update-klasse voor batches

Update[A] is een voorbereide, geparametriseerde instructie die je meerdere keren kunt uitvoeren. Je definieert de SQL één keer met ?-plaatsaanduidingen en levert waarden van het type A.

Deze wordt opgebouwd uit een SQL-tekenreeks en een Write[A]-instantie.

val ins: Update[(String, Int)] =
  Update[(String, Int)]("insert into users (name, age) values (?, ?)")

Efficiënte batch-inserts

updateMany verstuurt een volledige verzameling in één JDBC-batch en is veel sneller dan afzonderlijke inserts in een lus uit te voeren.

De methode geeft het totale aantal gewijzigde rijen terug. Gebruik deze wanneer je veel rijen tegelijk laadt.

val rows = List(("Ada", 36), ("Linus", 54))

val batch: ConnectionIO[Int] = ins.updateMany(rows)

Batch-insert met sleutels

Update kan voor een batch ook gegenereerde sleutels streamen via updateManyWithGeneratedKeys. Daarbij krijg je één rij terug per ingevoegd record.

Zo combineer je bulkladen met het teruglezen van toegewezen identificatoren.

import fs2.Stream

val keyed: Stream[ConnectionIO, Long] =
  ins.updateManyWithGeneratedKeys[Long]("id")(rows)

Upserts met ON CONFLICT

Database-specifieke upserts werken prima via Doobie. In PostgreSQL schrijf je insert ... on conflict ... do update als gewone SQL.

Doobie bindt alleen je parameters; de semantiek van de upsert hoort bij de 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.run

Write-instanties en standaardwaarden

Parameters worden gecodeerd met de typeklasse Write[A], die wordt afgeleid voor primitieve typen, tuples en case classes. Elk veld heeft een Put-instantie nodig.

Als je een kolom weglaat uit de insert, past de database de DEFAULT toe. Zo ontstaan bijvoorbeeld gegenereerde tijdstempels.

case class NewUser(name: String, age: Int)

val mk = Update[NewUser](
  "insert into users (name, age) values (?, ?)"
)

Aangepaste kolomkoppelingen met Meta

Definieer een Meta[A] om een aangepast type op te slaan door het met imap (of timap) aan een bestaand kolomtype te koppelen.

Een Meta biedt zowel lees- als schrijfmogelijkheden, zodat het type zowel in query's als in updates werkt.

import doobie.util.meta.Meta

case class UserId(value: Long)

implicit val uidMeta: Meta[UserId] =
  Meta[Long].imap(UserId.apply)(_.value)

Deletes zijn ook updates

DELETE-instructies gebruiken ook .update.run en geven het aantal verwijderde rijen terug.

Door inserts, updates en deletes uniform als Update0 te behandelen, blijft de API klein en goed samen te stellen.

def purgeInactive: ConnectionIO[Int] =
  sql"delete from users where active = false".update.run

Snelle controle

Kies de efficiëntste aanpak.

Samenvatting

Schrijfbewerkingen gebruiken .update om een Update0 te maken; .run geeft gewijzigde rijen terug en .withUniqueGeneratedKeys leest gegenereerde waarden terug.

Voor bulkbewerkingen bundelt Update[A].updateMany efficiënt. Aangepaste typen krijgen Meta-instanties en upserts zijn gewoon normale databasesyntaxis die door Doobie wordt gebonden.

Gratis beginnen

Leer Scala met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
39
Lessen
143

Veelgestelde vragen

Is de les “Inserts en updates” gratis?

Ja — de volledige tekst van “Inserts en updates” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Scala voor backend-engineering en functioneel programmeren wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Scala voor backend-engineering en functioneel programmeren bevat in totaal 4 lessen.

Wat leer ik in “Inserts en updates”?

Schrijf gegevens functioneel. Je oefent met Scala voor backend-engineering en functioneel programmeren door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Scala voor backend-engineering en functioneel programmeren te beginnen?

Ervaring vooraf is niet nodig. Scala voor backend-engineering en functioneel programmeren op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.

Hoe lang duurt de les “Inserts en updates”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Scala voor backend-engineering en functioneel programmeren?

Ja. Elke les over Scala voor backend-engineering en functioneel programmeren bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Verbinden met een transactor
  2. Queries uitvoeren
  3. Inserts en updates
  4. Transacties samenstellen
← Terug naar Scala voor backend-engineering en functioneel programmeren