概要
slick で日付型を取得すると、デフォルトでは java.sql.Timestamp 型になってしまいます。
ビジネスロジックでは sql.* とかっていう型は使いたくないですよね。
java.util.Date も扱いにくいので、 joda.time.DateTime にしたいですよね。
というわけで簡単なコードを載せます。
※play2.5 scala 環境を前提としています。
実装
テーブルは以下とします。
schema.sql
CREATE TABLE IF NOT EXISTS SAMPLE (
SAMPLE_DAY timestamp NOT NULL
);
テーブルに対応する case class を定義します。
case class Sample(sampleDay:DateTime)
Tables.scala にテーブルとモデルの対応関係を定義します。
java.sql.Timestamp ⇒ joda.time.DateTime の変換処理も定義します。※この記事のポイントはここだけです・・・
Tables.scala
class Tables @Inject()(dbConfigProvider: DatabaseConfigProvider) {
val dbConfig = dbConfigProvider.get[JdbcProfile]
import dbConfig.driver.api._
/**
* java.sql.Timestamp ⇔ joda.time.DateTime
*/
implicit val jodatimeColumnType = MappedColumnType.base[DateTime, Timestamp](
{ jodatime => new Timestamp(jodatime.getMillis()) },
{ sqltime => new DateTime(sqltime.getTime) }
)
class SampleTable(tag: Tag) extends Table[Sample] (tag, "SAMPLE") {
def sampleDay = column[DateTime]("SAMPLE_DAY")
def * = (sampleDay) <> (Sample.tupled, Sample.unapply)
}
val samples = TableQuery[SampleTable]
使う側です。
class DBDAO @Inject() (dbConfigProvider:DatabaseConfigProvider, tables:Tables) extends DAO {
val dbConfig = dbConfigProvider.get[JdbcProfile]
import dbConfig.driver.api._
import scala.concurrent.ExecutionContext.Implicits.global
override def getSampleDay:DateTime = {
val f = dbConfig.db.run(tables.samples.result.head)
Await.result(f, Duration(1, SECONDS)).sampleDay
}
}
以上。
おまけ
DB の Int 型を Scala の Boolean 型に変換したい場合は以下のようにします。
変換の定義。
/**
* DB Int ⇔ Scala Boolean
*/
implicit val booleanColumnType = MappedColumnType.base[Boolean, Int](
{ b => if(b) 1 else 0 }, // map Boolean to Int
{ i => if(i == 0) false else true } // map Int to Boolean
)
Table のカラム指定。(isDisp というカラムだとします。)
def isDisp = column[Boolean]("ISDISP")