Создайте пользовательское сопоставление столбцов для java.time.LocalDate с Slick
Я использую Slick 3.1.0-M2, и я хочу использовать java.time.LocalDate и java.time.LocalTime в моих таблицах. Я делаю это так:
import java.sql.{Date, Time, Timestamp}
import java.time.{LocalDate, LocalTime, LocalDateTime, ZoneOffset}
trait DateTimeColumns {
import slick.driver.PostgresDriver.api._
implicit val localDateTimeColumnType = MappedColumnType.base[LocalDateTime, Timestamp](
d => Timestamp.from(d.toInstant(ZoneOffset.ofHours(0))),
d => d.toLocalDateTime
)
implicit val dateColumnType = MappedColumnType.base[LocalDate, Date](
d => Date.valueOf(d),
d => d.toLocalDate
)
implicit val timeColumnType = MappedColumnType.base[LocalTime, Time](
localTime => Time.valueOf(localTime),
time => time.toLocalTime
)
}
Итак, у меня есть 3 неявных отображения, но компилируется только первое. Те, у которых есть java.sql.Date и java.sql.Time, не компилируются:
could not find implicit value for evidence parameter of type slick.driver.PostgresDriver.BaseColumnType[java.sql.Date]
Когда я делаю неявную проверку параметров в IntelliJ, я вижу, что первое сопоставление находит TimestampJdbcType в файле JdbcTypesComponent.scala. Прямо рядом с этим я вижу TimeJdbcType и DateJdbcType. Так почему же первый найден, а другие нет?
1 ответ
Если вы проверите slick.driver.JdbcTypesComponent
, вы найдете trait ImplicitColumnTypes
содержит много последствий для типа столбца, в том числе:
implicit def timeColumnType = columnTypes.timeJdbcType
implicit def dateColumnType = columnTypes.dateJdbcType
Последние два, которые вы определили, на самом деле имеют то же имя, что и имена по умолчанию.
Изменение их имен или переименование по умолчанию при импорте работает для меня.
import slick.driver.PostgresDriver.api._
import slick.driver.PostgresDriver.api.{ timeColumnType => DefaultTimeColumnType }
implicit val myDateColumnType = MappedColumnType.base[LocalDate, Date](
ld => Date.valueOf(ld),
d => d.toLocalDate
)
implicit val timeColumnType = MappedColumnType.base[LocalTime, Time](
localTime => Time.valueOf(localTime),
time => time.toLocalTime
)