6장 데이터베이스 사용 방법과 ORM의 미래
Integrating an existing ORM – Hibernate and JPA
Object-relational mapping (ORM, O/RM, and O/R mapping tool) in computer science is a programming technique for converting data between incompatible type systems in object-oriented programming languages.
Making JPA available in Scala
sbt project 생성
$ mkdir sbtjpasample $ cd sbtjpasample $ sbt > set name:="sbtjpasample" > session save > exit
Project directory 에서 plugins.sbt 생성하고, addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.4.0") 추가하고,Eclipse 안 쓰는 관계로 .. PassintelliJ > import project 로 진행
- Scala Default Value
var id: Int = _ // _는 default value를 할당
- 0 if T is Int or one of its subrange types
- 0L if T is Long
- 0.0f if T is Float
- 0.0d if T is Double
- false if T is Boolean
- () if T is Unit
- null for all other types of T
- Sample Project - sbtjpasample (github 링크 추가 예정)
Dealing with persistence in the Play Framework
A simple example using Anorm
Anorm( Anorm is Not an Object Relational Mapper )
Play includes a simple data access layer called Anorm that uses plain SQL to interact with the database and provides an API to parse and transform the resulting datasets.
Add Anorm plugin...
- in Plugins.sbt
// The Play plugin addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.0")
- in Build.sbt
//2.4.x 이전 libraryDependencies ++= Seq( jdbc, anorm ) // 2.4.x 이후 libraryDependencies ++= Seq( jdbc, "com.typesafe.play" %% "anorm" % "2.4.0", )
2.4.x부터 play core lib에서 제외됨.(https://www.playframework.com/documentation/2.4.x/Anorm)
- in Plugins.sbt
책에 있는 예제는 이전 버전으로 대부분 deprecated 되었으므로, 최신 버전의 play documentation을 보는 것을 추천한다. version이 올라가면서 변경사항들이 많으니 꼭 version 별로 Documentation을 참조하고 Migration Guide 도 참조해야 한다.
Sample Project - playforscala23 (github 링크 추가 예정)
- Sample Project - playforscala (github 링크 추가 예정)
Replacing ORM
Slick(Scala Language-Integrated Connection Kit)
Slick is Typesafe‘s Functional Relational Mapping (FRM) library for Scala that makes it easy to work with relational databases. It allows you to work with stored data almost as if you were using Scala collections while at the same time giving you full control over when a database access happens and which data is transferred. You can also use SQL directly. Execution of database actions is done asynchronously, making Slick a perfect fit for your reactive applications based on Play and Akka.
- Slick은 관계형 DB를 Scala에서 (함수형 언어스럽게??) 쉽게 작업하기 위한 (ORM을 대체하는) FRM library 이다.
- Functional Relational Mapping
- Conciseness and Type Safety
- Composable and reusable queries
Learning about Slick
Adding Slick to Your Project
- in Build.sbt
libraryDependencies ++= Seq( "com.typesafe.slick" %% "slick" % "3.1.1", "org.slf4j" % "slf4j-nop" % "1.6.4" )
in application.conf
h2mem1 = { url = "jdbc:h2:mem:test1" driver = org.h2.Driver connectionPool = disabled keepAliveConnection = true }
in source
// Use H2Driver to connect to an H2 database import slick.driver.H2Driver.api._ import scala.concurrent.ExecutionContext.Implicits.global . . . val db = Database.forConfig("h2mem1") try { // ... } finally db.close
- in Build.sbt
Functional Relational Mapping
class Coffees(tag: Tag) extends Table[(String, Double)](tag, "COFFEES") { def name = column[String]("COF_NAME", O.PrimaryKey) def price = column[Double]("PRICE") def * = (name, price) } val coffees = TableQuery[Coffees] // Query that only returns the "name" column // Equivalent SQL: select NAME from COFFEES coffees.map(_.name) // Query that limits results by price < 10.0 // Equivalent SQL: select * from COFFEES where PRICE < 10.0 coffees.filter(_.price < 10.0) // Create a query for coffee names with a price less than 10, sorted by name coffees.filter(_.price < 10.0).sortBy(_.name).map(_.name) // The generated SQL is equivalent to: // select name from COFFEES where PRICE < 10.0 order by NAME
Scaffolding a Play application
Importing test data
Visualizing the database in the H2browser
sbt> h2-browse
Exploring the code behind the app generation
Limitations of the playcrud utility
Summary
버전업도 빠르고 각 버전업마다 변경사항도 많으니, 개발할때 library version check를 잘하고, Migration Guid도 꼭 참조하는 것이 좋을 것 같다.