0Pricing
Scala for Backend Engineering & Functional Programming · Leçon

Insertions et mises à jour

Écrivez les données de façon fonctionnelle.

Insertions et mises à jour est une leçon Scala for Backend Engineering & Functional Programming gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Scala for Backend Engineering & Functional Programming, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Scala for Backend Engineering & Functional Programming comprend 4 leçons au total.

Update0 pour les écritures

Les écritures utilisent le même interpolateur sql, mais vous appelez .update pour obtenir un Update0 plutôt qu'un .query.

L'exécution de .run sur un Update0 renvoie un ConnectionIO[Int] : le nombre de lignes affectées.

import doobie.implicits._

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

Nombre de lignes affectées

L'Int renvoyé par .run est le nombre de mises à jour JDBC. Pour un UPDATE ou un DELETE, il indique combien de lignes correspondaient.

Vous pouvez utiliser cette valeur pour détecter, par exemple, une mise à jour qui ne correspondait à aucune ligne.

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

Retour des clés générées

Pour obtenir une clé primaire générée automatiquement, utilisez .withUniqueGeneratedKeys en indiquant les colonnes renvoyées par la base de données.

Cela exécute l'insertion et relit les valeurs générées en un seul aller-retour.

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

Retour d'une ligne complète

Vous pouvez retourner plusieurs colonnes générées ou définies par défaut en les lisant dans un tuple ou une classe de cas.

C'est très utile pour récupérer les valeurs par défaut côté serveur, comme les horodatages, juste après l'insertion.

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 classe de mise à jour pour les traitements par lots

Update[A] est une instruction préparée et paramétrée que vous pouvez exécuter plusieurs fois. Vous définissez le SQL une seule fois avec des espaces réservés ?, puis fournissez des valeurs de type A.

Elle est construite à partir d'une chaîne SQL et d'une instance de Write[A].

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

Insertions par lots efficaces

updateMany envoie toute une collection en une seule opération JDBC par lots, bien plus rapidement qu'une boucle d'insertions individuelles.

La méthode retourne le nombre total de lignes affectées. Utilisez-la lorsque vous chargez beaucoup de lignes en une fois.

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

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

Insertion par lots avec des clés

Update peut également transmettre les clés générées pour un traitement par lots via updateManyWithGeneratedKeys, en renvoyant une ligne pour chaque enregistrement inséré.

Cela combine le chargement en masse et la lecture des identifiants attribués.

import fs2.Stream

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

Upserts avec ON CONFLICT

Les upserts propres à chaque base de données fonctionnent parfaitement avec Doobie. Avec PostgreSQL, vous écrivez normalement le SQL insert ... on conflict ... do update.

Doobie se contente de lier vos paramètres ; la sémantique de l'upsert appartient à la base de données.

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

Instances d'écriture et valeurs par défaut

Les paramètres sont encodés avec la classe de types Write[A], dérivée pour les types primitifs, les tuples et les classes de cas. Chaque champ nécessite une instance de Put.

Si vous omettez une colonne lors de l'insertion, la base de données applique sa valeur DEFAULT, ce qui permet notamment de générer des horodatages.

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

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

Mappages personnalisés de colonnes avec Meta

Pour conserver un type personnalisé, définissez un Meta[A] en le mappant vers un type de colonne existant avec imap (ou timap).

Un Meta fournit à la fois la lecture et l'écriture ; le type fonctionne donc aussi bien dans les requêtes que dans les mises à jour.

import doobie.util.meta.Meta

case class UserId(value: Long)

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

Les suppressions sont aussi des mises à jour

Les instructions DELETE utilisent également .update.run et retournent le nombre de lignes supprimées.

Traiter uniformément les insertions, les mises à jour et les suppressions comme des Update0 permet de conserver une API compacte et composable.

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

Vérification rapide

Choisissez l'approche la plus efficace.

Récapitulatif

Les écritures utilisent .update pour produire un Update0 ; .run retourne les lignes affectées et .withUniqueGeneratedKeys relit les valeurs générées.

Pour les traitements en masse, Update[A].updateMany effectue efficacement le traitement par lots. Les types personnalisés obtiennent des instances de Meta, et les upserts ne sont que du SQL normal de la base de données, auquel Doobie lie les paramètres.

Questions Fréquemment Posées

La leçon « Insertions et mises à jour » est-elle gratuite ?

Oui — le texte complet de « Insertions et mises à jour » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Scala for Backend Engineering & Functional Programming, passe à CoddyKit PRO. Le cours Scala for Backend Engineering & Functional Programming comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Insertions et mises à jour » ?

Écrivez les données de façon fonctionnelle. Tu pratiques Scala for Backend Engineering & Functional Programming avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Scala for Backend Engineering & Functional Programming ?

Aucune expérience préalable n'est requise. Scala for Backend Engineering & Functional Programming sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « Insertions et mises à jour » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Scala for Backend Engineering & Functional Programming ?

Oui. Chaque leçon Scala for Backend Engineering & Functional Programming inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Se connecter avec un transacteur
  2. Exécuter des requêtes
  3. Insertions et mises à jour
  4. Composer des transactions
← Retour à Scala for Backend Engineering & Functional Programming