はじめに
この間怒りに任せてあげた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も同様に書くことができると思います。