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 안 쓰는 관계로 .. Pass

  • intelliJ > 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)

  • 책에 있는 예제는 이전 버전으로 대부분 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
      
  • 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
    

    Slick Documentation(3.1.1) 참조.

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도 꼭 참조하는 것이 좋을 것 같다.