はじめに
この間怒りに任せてあげたSlickでいつの間にかjava.time.*がサポートされてた話ではMySQLのdatetime
やtimestamp
はjava.time.LocalDateTime
に相互変換されませんって話でした。
しかも以前はサポート対象外だったおかげて暗黙の変換を書いておけば問題なかったんですが、3.3以降、自分の環境ではjava.time.*
系の変換を書いちゃうとどっかで衝突すんのかコンパイルが通らなくなってしまいました(上記前記事参照)。
という訳で今回はどうにかして変換できるようにしてみます。
環境
scala: 2.12
slick: 3.3
型を作ってしまおう
しょうがないので間に型を咬ませます。
代表してdatetime
をサポートしてみます。
case class MySQLDateTime(value: String) {
def toLocalDateTime: LocalDateTime =
LocalDateTime.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
}
回りくどい気もしますが、値としてdatetime
をString
で保持し、LocalDateTime
として出力できるようにしています。
テーブルではこんな感じ
class TestTable(tag: Tag) extends Table[Test](tag, "test") {
// 抜粋
def testDate = column[MySQLDateTime]("test_date")
// 抜粋
}
このままでは当然MySQLDateTime
型は変換できないのでコンパイルは通りません。
暗黙の変換
上記テーブルに下記の暗黙の変換を追加します。
implicit lazy val mySqlDateTimeType: JdbcType[MySQLDateTime] with BaseTypedType[MySQLDateTime] =
MappedColumnType.base[MySQLDateTime, java.sql.Timestamp](
t => java.sql.Timestamp.valueOf(t.value),
u => MySQLDateTime(u.toLocalDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
)
テーブルからはjava.sql.Timestamp
として受けて相互変換可能としています。DateTimeFormatter...
云々はどこぞに固定値として生やした方が良いでしょう。
おわりに
timestamp
やdate
、time
も同様に書くことができると思います。