本文介绍了Slick SQL 的客户类型映射器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've found this example from slick testing:
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 和 java.sql.Timestamp 创建一个 TypeMapper - 但没有取得多大成功.Bool 示例非常特殊,我很难适应它.Joda Time 非常普遍 - 所以任何帮助将不胜感激.

But I'm trying to create a TypeMapper for org.joda.time.DateTime to/from java.sql.Timestamp - but without much success. The Bool example is very particular and I'm having trouble adapting it. Joda Time is super common - so any help would be much appreciated.

需要明确的是,我正在使用内插 sql"""select colA,colB from tableA where id = ${id}""" 等等.在进行选择时,系统通过在隐式 GetResult 转换器中使用 jodaDate 类型而运行良好.

To be clear, I'm using interpolated sql"""select colA,colB from tableA where id = ${id}""" and such. When doing a select the system works well by using jodaDate types in the implicit GetResult converter.

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

However, for inserts there doesn't seem to be a way to do an implicit conversion or it is ignoring the code provided below in Answer #1 - same error as before:could not find implicit value for parameter pconv: scala.slick.jdbc.SetParameter[(Option[Int], String, String, Option[org.joda.time.DateTime])]

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

I'm not using the Lifted style Slick configuration with the annotated Table objects perhaps that is why it is not finding/using the TypeMapper

推荐答案

我在我的代码中使用了以下内容,这可能也适用于您:

I use the following in my code, which might also work for you:

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))

编辑(在您编辑后 =^.~= ):(有点晚,但我希望它仍然有帮助)

Edit (after your edit =^.~= ): (a bit late but I hope it still helps)

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

Ah, OK, since you're not using lifted embedding, you'll have to define different implicit values (as indicated by the error message from the compiler). Something like the following should work (though I haven't tried myself):

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

反过来(检索 SELECT 的结果),您似乎需要定义一个 GetResult:

For the other way round (retrieving the results of the SELECT), it looks like you'd need to define a GetResult:

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

所以,基本上这和提升嵌入是一样的,只是用不同的类型编码.

So, basically this is just the same as with the lifted embedding, just encoded with different types.

这篇关于Slick SQL 的客户类型映射器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 15:47