Slick/Doobie를 활용한 데이터베이스 통합
Slick 또는 Doobie 같은 Scala ORM/라이브러리를 사용해 데이터베이스를 Play 애플리케이션에 통합하는 방법을 배웁니다.
Slick/Doobie를 활용한 데이터베이스 통합은(는) CoddyKit의 무료 Scala for Backend Engineering & Functional Programming 강의입니다. 이것은 3개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Scala for Backend Engineering & Functional Programming 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Scala for Backend Engineering & Functional Programming 강의에는 총 3개의 강의가 포함되어 있습니다.
데이터베이스를 통합하는 이유
웹 애플리케이션은 데이터를 영구적으로 저장하고 조회해야 하는 경우가 많습니다. 데이터에는 사용자 프로필, 상품 정보 또는 블로그 게시물이 포함될 수 있습니다.
- 영속성: 애플리케이션이 다시 시작된 후에도 데이터를 사용할 수 있습니다.
- 확장성: 많은 양의 데이터와 다수의 동시 사용자를 처리할 수 있습니다.
- 신뢰성: 데이터 무결성과 복구 가능성을 보장합니다.
Play Framework로 구축하는 모든 동적 웹 애플리케이션에서 데이터베이스 통합은 매우 중요합니다.
Slick 및 Doobie: Scala의 데이터베이스 도구
Scala는 데이터베이스와 상호 작용할 수 있는 강력한 라이브러리를 제공하며, Slick과 Doobie가 널리 사용되는 두 가지 선택지입니다.
- Slick: 함수형 관계 매핑(FRM) 라이브러리입니다. SQL을 추상화하여 타입 안전하고 함수형인 방식으로 데이터베이스를 사용할 수 있게 해 줍니다.
- Doobie: 순수 함수형 JDBC 계층입니다. Cats Effect와 같은 함수형 프로그래밍 패러다임과 통합하면서 SQL 쿼리를 직접 제어할 수 있게 해 줍니다.
이 강의에서는 더 높은 수준의 추상화를 제공하여 Play Framework와의 초기 통합을 간소화하는 경우가 많은 Slick에 집중하겠습니다.
Play에서 Slick 설정하기
먼저 build.sbt에 Slick과 데이터베이스 드라이버를 추가합니다. 쉽게 설정할 수 있도록 인메모리 데이터베이스인 H2를 사용하겠습니다.
그런 다음 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"
)데이터베이스 구성
H2 데이터베이스와 Slick 프로필을 설정하려면 conf/application.conf에 다음 줄을 추가합니다. slick.dbs.default.profile은 데이터베이스 유형을 지정합니다.
play.db.prototype.slick은 데이터베이스 연결을 위한 템플릿을 정의합니다.
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}
}모델 정의하기(Slick 테이블)
Slick에서는 slick.jdbc.H2Profile.api.Table을 확장하는 Scala 클래스를 사용하여 데이터베이스 테이블을 나타냅니다. 각 열은 Scala 타입에 매핑됩니다.
각 테이블에 대해 쿼리를 실행하는 시작점인 TableQuery를 정의합니다.
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]코드: 테이블 및 스키마 생성
이 실행 가능한 예제에서는 User 테이블을 정의한 다음 인메모리 H2 데이터베이스에 해당 스키마를 생성하는 방법을 보여 줍니다. db.run 메서드는 데이터베이스 동작을 비동기적으로 실행합니다.
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 패턴
데이터 접근 객체(DAO) 패턴은 데이터베이스 작업을 캡슐화하는 데 도움이 됩니다. 이를 통해 애플리케이션의 비즈니스 로직과 영속성 로직을 분리할 수 있습니다.
UserDAO에는 User 객체를 삽입하고, 조회하고, 수정하고, 삭제하는 메서드가 포함됩니다.
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)
}
}코드: 데이터 삽입 및 조회
방금 정의한 DAO 메서드를 사용하여 새 사용자를 삽입한 다음 데이터베이스에서 모든 사용자를 조회하는 방법은 다음과 같습니다.
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()
}
}
}Play에 DAO 통합하기
Play 애플리케이션에서는 일반적으로 의존성 주입을 사용하여 UserDAO를 컨트롤러에 주입합니다. 이를 통해 컨트롤러 동작이 데이터베이스와 상호 작용할 수 있습니다.
Play의 DI(예: Guice)를 구성하여 Database와 UserDAO의 인스턴스를 제공하도록 설정합니다.
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")))
}
}빠른 확인: Slick 테이블
다음 Scala 케이스 클래스와 일부만 정의된 Slick Table 매핑을 살펴보세요.
case class Product(id: Option[Int], name: String, price: Double)id, name, price 열이 정의되어 있다고 할 때, Product 테이블의 * 프로젝션을 올바르게 완성하는 줄은 무엇입니까?
복습: 데이터베이스 통합
이 강의에서는 Slick을 사용하여 Play Framework 애플리케이션에 데이터베이스를 통합하는 방법을 살펴보았습니다.
- Slick이 함수형 관계 매핑(FRM) 라이브러리로서 어떤 역할을 하는지 배웠습니다.
- Slick 의존성을 설정하고
application.conf에서 데이터베이스를 구성하는 방법을 다루었습니다. - Scala 케이스 클래스를 정의하고 Slick의
Table클래스를 사용하여 데이터베이스 테이블에 매핑하는 방법을 살펴보았습니다. - 데이터베이스 작업을 구성하기 위한 DAO 패턴을 소개하고 데이터 삽입 및 조회 예제를 살펴보았습니다.
- 마지막으로 웹 API 엔드포인트를 위한 Play 컨트롤러에 이러한 DAO 작업을 통합하는 방법을 간단히 알아보았습니다.
데이터베이스 통합을 능숙하게 활용하는 것은 견고하고 데이터 중심적인 Play 애플리케이션을 구축하는 데 핵심입니다!
자주 묻는 질문
“Slick/Doobie를 활용한 데이터베이스 통합” 강의는 무료인가요?
네 — “Slick/Doobie를 활용한 데이터베이스 통합” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Scala for Backend Engineering & Functional Programming 강의 전체를 잠금 해제할 수 있습니다. Scala for Backend Engineering & Functional Programming 강의에는 총 3개의 강의가 포함되어 있습니다.
“Slick/Doobie를 활용한 데이터베이스 통합”에서 뭘 배우나요?
Slick 또는 Doobie 같은 Scala ORM/라이브러리를 사용해 데이터베이스를 Play 애플리케이션에 통합하는 방법을 배웁니다. 브라우저에서 직접 실행하는 실습 코드로 Scala for Backend Engineering & Functional Programming을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Scala for Backend Engineering & Functional Programming을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Scala for Backend Engineering & Functional Programming은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 3개 중 3번째 강의입니다.
“Slick/Doobie를 활용한 데이터베이스 통합” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Scala for Backend Engineering & Functional Programming 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Scala for Backend Engineering & Functional Programming 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- Play 프레임워크 기초
- Play로 RESTful API 구축
- Slick/Doobie를 활용한 데이터베이스 통합