Eseguire query
Legga le righe nelle case class.
Eseguire query è una lezione Scala for Backend Engineering & Functional Programming gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Scala for Backend Engineering & Functional Programming, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Scala for Backend Engineering & Functional Programming include 4 lezioni in totale.
L’interpolatore sql
L’interpolatore di stringhe sql di Doobie è il cuore delle query. Analizza il codice SQL e trasforma i valori Scala incorporati in parametri associati in modo sicuro.
I valori interpolati diventano placeholder JDBC ?, quindi non ci sono rischi di SQL injection né cablaggio manuale di PreparedStatement.
import doobie.implicits._
val minAge = 18
val frag = sql"select name from users where age >= $minAge"Dal Fragment alla query
Un'espressione sql"..." è un Fragment. Per eseguirla come lettura si chiama .query[A], scegliendo il tipo di riga A.
Doobie usa il typeclass Read[A] per mappare le colonne del risultato su A, supportando tipi primitivi, tuple e case class.
case class User(name: String, age: Int)
val q: Query0[User] =
sql"select name, age from users".query[User]unique, option e to
Un Query0[A] offre diversi accumulatori. .unique si aspetta esattamente una riga, .option da zero o una riga e .to[List] raccoglie tutte le righe.
Ognuno restituisce una ConnectionIO su cui in seguito si chiama .transact.
val one: ConnectionIO[User] = q.unique
val maybe: ConnectionIO[Option[User]] = q.option
val all: ConnectionIO[List[User]] = q.to[List]Mappare le righe su case class
Doobie ricava automaticamente le istanze Read per le case class quando ogni campo dispone di un mapping di colonna. L'ordine delle colonne deve corrispondere a quello dell'elenco di selezione.
Questo consente di eseguire la selezione direttamente in tipi di dominio ricchi, senza codice ripetitivo per analizzare le righe.
case class Account(id: Long, email: String, active: Boolean)
val accounts =
sql"select id, email, active from accounts"
.query[Account].to[Vector]Query parametrizzate
Ogni valore Scala interpolato viene associato come parametro usando la relativa istanza Put. È possibile interpolarne quanti se ne desiderano, anche in posizioni diverse.
Poiché vengono associati e non concatenati, i tipi vengono verificati e l'injection è impossibile.
def findByEmail(email: String): ConnectionIO[Option[Account]] =
sql"select id, email, active from accounts where email = $email"
.query[Account].optionTrasmettere grandi quantità di risultati
Per insiemi di risultati molto grandi, usi .stream per ottenere uno Stream[ConnectionIO, A] di fs2. Le righe vengono recuperate in modo lazy con un cursore lato server, mantenendo limitato l'uso della memoria.
Lo combini con i combinatori di fs2 per elaborare milioni di righe in modo incrementale.
import fs2.Stream
val s: Stream[ConnectionIO, Account] =
sql"select id, email, active from accounts"
.query[Account].streamControllare la dimensione del fetch
Con alcuni driver, la dimensione predefinita del fetch del cursore può caricare tutto in una volta. .streamWithChunkSize(n) imposta la dimensione di fetch JDBC, così il cursore recupera n righe per ogni round trip.
La regolazione di questo valore bilancia i round trip e l'uso della memoria.
val s =
sql"select id, email, active from accounts"
.query[Account]
.streamWithChunkSize(512)Colonne opzionali e nullabilità
Le colonne nullable vengono mappate su Option[A] nel tipo delle righe. Se una colonna può contenere NULL, deve essere letta come Option, altrimenti Doobie genera un'eccezione quando trova un valore null.
In questo modo la nullabilità è esplicita e type-safe al confine del sistema.
case class Person(id: Long, nickname: Option[String])
val ps =
sql"select id, nickname from people".query[Person].to[List]Costruire SQL con i Fragment
I valori Fragment si compongono con ++, consentendo di assemblare le query a partire da più parti mantenendo associati i parametri.
L'interpolatore fr costruisce un fragment con uno spazio finale, utile per concatenare le clausole.
val base = fr"select id, email, active from accounts"
val where = fr"where active = $${true}"
val q = (base ++ where).query[Account]Clausole WHERE dinamiche
Gli helper Fragments di Doobie costruiscono clausole condizionali. Fragments.whereAndOpt combina filtri opzionali, includendo solo quelli presenti.
Questo è il modo idiomatico per costruire query di ricerca dinamiche e sicure.
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)Verificare le query al momento della compilazione
L'analisi check di Doobie esegue una query sullo schema del database per verificare che tipi e numero delle colonne corrispondano ai tipi Scala.
Usata nei test, rileva le modifiche incompatibili dello schema prima che arrivino in produzione.
import doobie.scalatest._
// inside a spec mixing in IOChecker
check(sql"select id, email, active from accounts".query[Account])Verifica rapida
Scelga l'accumulatore corretto.
Riepilogo
L'interpolatore sql costruisce Fragment parametrizzati; .query[A] li trasforma in un Query0[A] mappato tramite Read[A].
Scelga .unique, .option, .to[List] o .stream per accumulare le righe. Usi Fragments per le clausole dinamiche e check per validare la query rispetto allo schema.
Domande Frequenti
La lezione «Eseguire query» è gratuita?
Sì — il testo completo di «Eseguire query» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Scala for Backend Engineering & Functional Programming, passa a CoddyKit PRO. Il corso Scala for Backend Engineering & Functional Programming include 4 lezioni in totale.
Cosa imparerò in «Eseguire query»?
Legga le righe nelle case class. Eserciti Scala for Backend Engineering & Functional Programming con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Scala for Backend Engineering & Functional Programming?
Non è richiesta alcuna esperienza precedente. Scala for Backend Engineering & Functional Programming su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «Eseguire query»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Scala for Backend Engineering & Functional Programming?
Sì. Ogni lezione Scala for Backend Engineering & Functional Programming include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.