Slick SQL的客户类型映射器

时间:2013-02-11 18:49:23

标签: scala slick

我从光滑的测试中找到了这个例子:
https://github.com/slick/slick/blob/master/slick-testkit/src/main/scala/com/typesafe/slick/testkit/tests/MapperTest.scala

sealed trait Bool
case object True extends Bool
case object False extends Bool

implicit val boolTypeMapper = MappedColumnType.base[Bool, String](
  { b =>
    assertNotNull(b)
    if(b == True) "y" else "n"
  }, { i =>
    assertNotNull(i)
    if(i == "y") True else False
  }
)

但是我正在尝试为org.joda.time.DateTime创建一个TypeMapper到/来自java.sql.Timestamp - 但没有太大的成功。 Bool的例子非常特别,我在修改它时遇到了麻烦。 Joda Time非常普遍 - 所以任何帮助都会非常受欢迎。

要清楚,我正在使用插值的sql“”“从tableA中选择colA,colB,其中id = $ {id}”“”等等。在进行选择时,通过在隐式GetResult转换器中使用jodaDate类型,系统运行良好。

但是,对于插入,似乎没有办法进行隐式转换,或者它忽略了答案#1中提供的代码 - 与以前相同的错误: 找不到参数pconv的隐含值:scala.slick.jdbc.SetParameter [(Option [Int],String,String,Option [org.joda.time.DateTime])]

我没有使用带有带注释的Table对象的Lifted样式Slick配置,这可能就是为什么它没有找到/使用TypeMapper

2 个答案:

答案 0 :(得分:14)

我在我的代码中使用以下内容,这可能对您有用:

import java.sql.Timestamp
import org.joda.time.DateTime
import org.joda.time.DateTimeZone.UTC
import scala.slick.lifted.MappedTypeMapper.base
import scala.slick.lifted.TypeMapper

implicit val DateTimeMapper: TypeMapper[DateTime] = 
  base[DateTime, Timestamp](
    d => new Timestamp(d millis), 
    t => new DateTime(t getTime, UTC))

编辑(编辑后= ^。〜=):(稍晚但我希望它仍有帮助)

啊,好的,因为你没有使用提升嵌入,你必须定义不同的隐含值(如编译器的错误消息所示)。像下面这样的东西应该工作(虽然我没有尝试过自己):

implicit val SetDateTime: SetParameter[DateTime] = new SetParameter { 
  def apply(d: DateTime, p: PositionedParameters): Unit =
    p setTimestamp (new Timestamp(d millis))
}

反过来(检索SELECT的结果),看起来您需要定义GetResult

implicit val GetDateTime: GetResult[DateTime] = new GetResult {
  def apply(r: PositionedResult) = new DateTime(r.nextTimestamp getTime, UTC))
}

所以,基本上这与使用不同类型编码的提升嵌入相同。

答案 1 :(得分:4)

为什么不挖掘出效果很好的东西呢? 看看

https://gist.github.com/dragisak/4756344

https://github.com/tototoshi/slick-joda-mapper

首先,您可以复制粘贴到您的项目,第二个可以从Maven central获得。