Datenbankintegration mit Slick/Doobie
Lernen Sie, Datenbanken mithilfe beliebter Scala-ORMs und -Bibliotheken wie Slick oder Doobie in Ihre Play-Anwendung zu integrieren.
Datenbankintegration mit Slick/Doobie ist eine kostenlose Scala for Backend Engineering & Functional Programming-Lektion auf CoddyKit. Dies ist Lektion 3 von 3. 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 3 Lektionen.
Warum Datenbanken integrieren?
Webanwendungen müssen häufig Daten dauerhaft speichern und abrufen. Dabei kann es sich um Benutzerprofile, Produktinformationen oder Blogbeiträge handeln.
- Persistenz: Die Daten bleiben auch nach einem Neustart der Anwendung verfügbar.
- Skalierbarkeit: Große Datenmengen und viele gleichzeitige Benutzer verarbeiten.
- Zuverlässigkeit: Datenintegrität und Wiederherstellbarkeit gewährleisten.
Die Integration einer Datenbank ist für jede dynamische Webanwendung mit dem Play Framework entscheidend.
Slick und Doobie: Datenbankwerkzeuge für Scala
Scala bietet leistungsfähige Bibliotheken für die Interaktion mit Datenbanken. Slick und Doobie gehören zu den beliebtesten Optionen.
- Slick: Eine Bibliothek für funktionales relationales Mapping (FRM). Sie ermöglicht Ihnen, typsicher und funktional mit Datenbanken zu arbeiten, während SQL abstrahiert wird.
- Doobie: Eine rein funktionale JDBC-Schicht. Sie bietet Ihnen direkte Kontrolle über SQL-Abfragen und lässt sich gleichzeitig in Paradigmen der funktionalen Programmierung wie Cats Effect integrieren.
In dieser Lektion konzentrieren wir uns aufgrund der höheren Abstraktion auf Slick, die die anfängliche Integration in das Play Framework häufig vereinfacht.
Slick in Play einrichten
Fügen Sie zunächst Slick und einen Datenbanktreiber zu Ihrer build.sbt hinzu. Für eine einfache Einrichtung verwenden wir H2, eine In-Memory-Datenbank.
Konfigurieren Sie anschließend Ihre Datenbankverbindung in conf/application.conf.
import play.sbt.PlayImport._
libraryDependencies ++= Seq(
jdbc,
ws,
"com.typesafe.play" %% "play-slick" % "5.0.0",
"com.typesafe.play" %% "play-slick-evolutions" % "5.0.0",
"com.h2database" % "h2" % "2.2.224"
)Datenbankkonfiguration
Fügen Sie diese Zeilen zu Ihrer conf/application.conf hinzu, um die H2-Datenbank und das Slick-Profil einzurichten. slick.dbs.default.profile legt den Datenbanktyp fest.
play.db.prototype.slick definiert eine Vorlage für Datenbankverbindungen.
slick.dbs.default.profile="slick.jdbc.H2Profile$"
play.db {
prototype.slick = {
db.driver="org.h2.Driver"
db.url="jdbc:h2:mem:play;DB_CLOSE_DELAY=-1"
db.username="sa"
db.password=""
}
# Apply the prototype to our default DB
default = ${play.db.prototype.slick}
}Ihr Modell definieren (Slick-Tabelle)
In Slick stellen Sie Datenbanktabellen als Scala-Klassen dar, die slick.jdbc.H2Profile.api.Table erweitern. Jede Spalte wird einem Scala-Typ zugeordnet.
Für jede Tabelle definieren wir eine TableQuery, die als Einstiegspunkt für Abfragen dient.
import slick.jdbc.H2Profile.api._
// Define a case class for our data model
case class User(id: Option[Long], name: String, email: String)
// Define the table mapping
class Users(tag: Tag) extends Table[User](tag, "users") {
def id = column[Option[Long]]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def email = column[String]("email")
// Every table needs a * projection with the default mapping
def * = (id, name, email) <> (User.tupled, User.unapply)
}
// TableQuery for accessing the Users table
val users = TableQuery[Users]Code: Tabelle und Schema erstellen
Dieses ausführbare Beispiel zeigt, wie Sie eine User-Tabelle definieren und anschließend ihr Schema in einer H2-In-Memory-Datenbank erstellen. Die Methode db.run führt Datenbankaktionen asynchron aus.
import slick.jdbc.H2Profile.api._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await
import scala.concurrent.duration._
case class User(id: Option[Long], name: String, email: String)
class Users(tag: Tag) extends Table[User](tag, "users") {
def id = column[Option[Long]]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def email = column[String]("email")
def * = (id, name, email) <> (User.tupled, User.unapply)
}
object SlickDemo {
val users = TableQuery[Users]
def main(args: Array[String]): Unit = {
val db = Database.forURL("jdbc:h2:mem:test1;DB_CLOSE_DELAY=-1", driver = "org.h2.Driver")
try {
val setup = DBIO.seq(
users.schema.create
)
val future = db.run(setup)
Await.result(future, 2.seconds)
println("Users table created successfully!")
} finally {
db.close()
}
}
}DAO-Muster für Operationen
Das Data-Access-Object-(DAO-)Muster kapselt Datenbankoperationen. Es trennt die Geschäftslogik Ihrer Anwendung von ihrer Persistenzlogik.
Ein UserDAO würde Methoden zum Einfügen, Abfragen, Aktualisieren und Löschen von User-Objekten enthalten.
import slick.jdbc.H2Profile.api._
import scala.concurrent.Future
class UserDAO(db: Database) {
import SlickDemo.users // Assuming users TableQuery is in SlickDemo object
def insert(user: User): Future[User] = {
db.run(users returning users.map(_.id) into ((user, id) => user.copy(id = id)) += user)
}
def findAll(): Future[Seq[User]] = {
db.run(users.result)
}
def findById(id: Long): Future[Option[User]] = {
db.run(users.filter(_.id === id).result.headOption)
}
}Code: Daten einfügen und abfragen
So fügen Sie einen neuen Benutzer ein und fragen anschließend mithilfe der gerade definierten DAO-Methoden alle Benutzer aus der Datenbank ab.
import slick.jdbc.H2Profile.api._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await
import scala.concurrent.duration._
case class User(id: Option[Long], name: String, email: String)
class Users(tag: Tag) extends Table[User](tag, "users") {
def id = column[Option[Long]]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def email = column[String]("email")
def * = (id, name, email) <> (User.tupled, User.unapply)
}
class UserDAO(db: Database) {
val users = TableQuery[Users]
def insert(user: User): Future[User] =
db.run(users returning users.map(_.id) into ((u, id) => u.copy(id = id)) += user)
def findAll(): Future[Seq[User]] =
db.run(users.result)
}
object SlickOperations {
def main(args: Array[String]): Unit = {
val db = Database.forURL("jdbc:h2:mem:test2;DB_CLOSE_DELAY=-1", driver = "org.h2.Driver")
val userDAO = new UserDAO(db)
try {
Await.result(db.run(userDAO.users.schema.create), 2.seconds)
println("Table created.")
val future = for {
user1 <- userDAO.insert(User(None, "Alice", "alice@example.com"))
user2 <- userDAO.insert(User(None, "Bob", "bob@example.com"))
allUsers <- userDAO.findAll()
} yield allUsers
val result = Await.result(future, 5.seconds)
println(s"All users: $result")
} finally {
db.close()
}
}
}DAO in Play integrieren
In einer Play-Anwendung injizieren Sie Ihren UserDAO üblicherweise mithilfe von Dependency Injection in einen Controller. Dadurch können Ihre Controller-Aktionen mit der Datenbank interagieren.
Sie würden die DI von Play (z. B. Guice) so konfigurieren, dass eine Instanz von Database und UserDAO bereitgestellt wird.
import play.api.mvc._
import play.api.libs.json._
import scala.concurrent.ExecutionContext
import javax.inject._
// Assuming User and UserDAO are defined as before
@Singleton
class UserController @Inject()(cc: ControllerComponents, userDAO: UserDAO)
(implicit ec: ExecutionContext) extends AbstractController(cc) {
def listUsers = Action.async {
userDAO.findAll().map { users =>
Ok(Json.toJson(users))
}
}
def createUser = Action.async(parse.json) {
request =>
request.body.validate[User].map { user =>
userDAO.insert(user).map(u => Created(Json.toJson(u)))
}.getOrElse(Future.successful(BadRequest("Invalid User Data")))
}
}Kurzer Check: Slick-Tabelle
Betrachten Sie die folgende Scala-Case-Klasse und ein teilweise definiertes Slick-Table-Mapping:
case class Product(id: Option[Int], name: String, price: Double)Welche Zeile vervollständigt die *-Projektion für die Product-Tabelle korrekt, wenn die Spalten id, name und price definiert sind?
Zusammenfassung: Datenbankintegration
In dieser Lektion haben wir untersucht, wie Sie mithilfe von Slick Datenbanken in Ihre Play-Framework-Anwendungen integrieren.
- Wir haben Slicks Rolle als Bibliothek für funktionales relationales Mapping (FRM) kennengelernt.
- Wir haben das Einrichten der Slick-Abhängigkeiten und das Konfigurieren der Datenbank in
application.confbehandelt. - Sie haben gesehen, wie sich Scala-Case-Klassen definieren und mithilfe der Slick-
Table-Klasse Datenbanktabellen zuordnen lassen. - Wir haben das DAO-Muster zur Organisation von Datenbankoperationen vorgestellt und Beispiele zum Einfügen und Abfragen von Daten gegeben.
- Zum Schluss haben wir die Integration dieser DAO-Operationen in Play-Controller für Web-API-Endpunkte behandelt.
Die Beherrschung der Datenbankintegration ist entscheidend für robuste und datengetriebene Play-Anwendungen!
Häufig gestellte Fragen
Ist die Lektion „Datenbankintegration mit Slick/Doobie“ kostenlos?
Ja — der vollständige Text von „Datenbankintegration mit Slick/Doobie“ 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 3 Lektionen.
Was lerne ich in „Datenbankintegration mit Slick/Doobie“?
Lernen Sie, Datenbanken mithilfe beliebter Scala-ORMs und -Bibliotheken wie Slick oder Doobie in Ihre Play-Anwendung zu integrieren. 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 3.
Wie lange dauert die Lektion „Datenbankintegration mit Slick/Doobie“?
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
- Grundlagen des Play Frameworks
- RESTful APIs mit Play entwickeln
- Datenbankintegration mit Slick/Doobie