Abfragen ausführen
Lesen Sie Zeilen in Case Classes ein.
Abfragen ausführen ist eine kostenlose Scala for Backend Engineering & Functional Programming-Lektion auf CoddyKit. Dies ist Lektion 2 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.
Der sql-Interpolator
Doobies sql-String-Interpolator bildet den Kern der Abfragen. Er parst Ihr SQL und wandelt eingebettete Scala-Werte in sichere gebundene Parameter um.
Interpolierte Werte werden zu JDBC-?-Platzhaltern, sodass weder SQL-Injection noch eine manuelle Verdrahtung von PreparedStatement möglich ist.
import doobie.implicits._
val minAge = 18
val frag = sql"select name from users where age >= $minAge"Vom Fragment zur Abfrage
Ein sql"..."-Ausdruck ist ein Fragment. Um ihn als Abfrage auszuführen, rufen Sie .query[A] auf und wählen den Zeilentyp A.
Doobie verwendet die Typklasse Read[A], um Ergebnisspalten auf A abzubilden. Dabei werden primitive Typen, Tupel und Case-Klassen unterstützt.
case class User(name: String, age: Int)
val q: Query0[User] =
sql"select name, age from users".query[User]unique, option und to
Ein Query0[A] bietet verschiedene Akkumulatoren. .unique erwartet genau eine Zeile, .option null oder eine Zeile und .to[List] sammelt alle Zeilen.
Jeder dieser Aufrufe liefert ein ConnectionIO, das Sie später mit .transact ausführen.
val one: ConnectionIO[User] = q.unique
val maybe: ConnectionIO[Option[User]] = q.option
val all: ConnectionIO[List[User]] = q.to[List]Zeilen auf Case-Klassen abbilden
Doobie leitet automatisch Read-Instanzen für Case-Klassen ab, wenn für jedes Feld eine Spaltenzuordnung vorhanden ist. Die Reihenfolge der Spalten muss der Select-Liste entsprechen.
So können Sie direkt in umfangreiche Domänentypen selektieren, ohne eine manuelle Zeilenverarbeitung zu schreiben.
case class Account(id: Long, email: String, active: Boolean)
val accounts =
sql"select id, email, active from accounts"
.query[Account].to[Vector]Parametrisierte Abfragen
Jeder interpolierte Scala-Wert wird mithilfe seiner Put-Instanz als Parameter gebunden. Sie können beliebig viele Werte interpolieren, auch an unterschiedlichen Stellen.
Da die Werte gebunden und nicht verkettet werden, werden die Typen geprüft und SQL-Injection ist ausgeschlossen.
def findByEmail(email: String): ConnectionIO[Option[Account]] =
sql"select id, email, active from accounts where email = $email"
.query[Account].optionGroße Ergebnismengen streamen
Für große Ergebnismengen verwenden Sie .stream, um einen fs2-Stream[ConnectionIO, A] zu erhalten. Die Zeilen werden mithilfe eines serverseitigen Cursors verzögert abgerufen, sodass der Speicherbedarf begrenzt bleibt.
Kombinieren Sie den Stream mit fs2-Kombinatoren, um Millionen von Zeilen schrittweise zu verarbeiten.
import fs2.Stream
val s: Stream[ConnectionIO, Account] =
sql"select id, email, active from accounts"
.query[Account].streamAbrufgröße steuern
Die standardmäßige Cursor-Abrufgröße lädt bei manchen Treibern möglicherweise alles auf einmal. .streamWithChunkSize(n) legt die JDBC-Abrufgröße fest, sodass der Cursor pro Roundtrip n Zeilen abruft.
Durch die Abstimmung lässt sich ein Ausgleich zwischen Roundtrips und Speicherbedarf erreichen.
val s =
sql"select id, email, active from accounts"
.query[Account]
.streamWithChunkSize(512)Optionale Spalten und Nullbarkeit
NULL-fähige Spalten werden in Ihrem Zeilentyp auf Option[A] abgebildet. Wenn eine Spalte NULL enthalten kann, müssen Sie sie als Option lesen, andernfalls löst Doobie bei einem Nullwert eine Ausnahme aus.
Dadurch wird die Nullbarkeit an der Grenze explizit und typsicher.
case class Person(id: Long, nickname: Option[String])
val ps =
sql"select id, nickname from people".query[Person].to[List]SQL mit Fragments erstellen
Fragment-Werte lassen sich mit ++ kombinieren. So können Sie Abfragen aus einzelnen Teilen zusammensetzen und gleichzeitig Parameter gebunden halten.
Der fr-Interpolator erstellt ein Fragment mit einem abschließenden Leerzeichen, was beim Zusammenfügen von Klauseln praktisch ist.
val base = fr"select id, email, active from accounts"
val where = fr"where active = $${true}"
val q = (base ++ where).query[Account]Dynamische WHERE-Klauseln
Die Fragments-Hilfsfunktionen von Doobie erstellen bedingte Klauseln. Fragments.whereAndOpt kombiniert optionale Filter und gibt nur die vorhandenen aus.
Dies ist der idiomatische Weg, sichere dynamische Suchabfragen zu erstellen.
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)Abfragen zur Build-Zeit prüfen
Die check-Analyse von Doobie führt eine Abfrage gegen das Datenbankschema aus, um zu überprüfen, ob Spaltentypen und -anzahl mit Ihren Scala-Typen übereinstimmen.
In Tests eingesetzt, erkennt sie Schemaänderungen, bevor diese die Produktion erreichen.
import doobie.scalatest._
// inside a spec mixing in IOChecker
check(sql"select id, email, active from accounts".query[Account])Schnelltest
Wählen Sie den passenden Akkumulator.
Zusammenfassung
Der sql-Interpolator erstellt parametrisierte Fragments; .query[A] wandelt sie in ein über Read[A] abgebildetes Query0[A] um.
Wählen Sie .unique, .option, .to[List] oder .stream, um Zeilen zu akkumulieren. Verwenden Sie Fragments für dynamische Klauseln und check, um die Abfrage gegen das Schema zu validieren.
Häufig gestellte Fragen
Ist die Lektion „Abfragen ausführen“ kostenlos?
Ja — der vollständige Text von „Abfragen ausführen“ 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 „Abfragen ausführen“?
Lesen Sie Zeilen in Case Classes ein. 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 2 von 4.
Wie lange dauert die Lektion „Abfragen ausführen“?
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.