Scala Slick在原始SQL查询中隐式转换多种类型 [英] Scala Slick implicit conversion of multiple types in raw SQL query

查看:96
本文介绍了Scala Slick在原始SQL查询中隐式转换多种类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究Scala Play Framework 2.2项目,并且正在使用play-slick 0.5.0.8作为我的数据库访问层.

I'm working on a Scala Play Framework 2.2 project, and I'm using play-slick 0.5.0.8 as my DB access layer.

我的一个DAO对象中包含以下代码:

I have the following code in one of my DAO objects:

def randomByBlahAndDate(blah: Blah, newerThan: LocalDate)(implicit s: Session): Option[Photo] = {
  sql"select * from photos where blah = $blah and imgDate > $newerThan order by rand()".as[Photo].headOption
}

如您所见,它做了一些棘手的事情,例如通过rand()进行排序,这就是为什么我决定采用原始SQL路由的原因.无论如何,我在编译时都会遇到以下错误:

As you can see, it does some tricky stuff like ordering by rand(), which is why I decided to go the raw SQL route. In any case, I get the following error on compilation:

could not find implicit value for parameter pconv: scala.slick.jdbc.SetParameter[(models.Blah.Blah, org.joda.time.LocalDate)]

看起来像是slick正在尝试将我的两种类型转换为一组,这很奇怪.我在Blah枚举上有一个隐式类型转换器,当插入和获取Photo对象时,该转换器可以正常工作:

It appears as though slick is trying to convert both of my types together, as a set... strange. I have an implicit type converter on my Blah enumeration, which works properly when inserting and fetching Photo objects:

def enumToStringMapper(enum: Enumeration) = MappedTypeMapper.base[enum.Value, String](
enum   => enum.toString,
string => enum.withName(string))

implicit val FormatMapper = enumToStringMapper(Blah)

我也import com.github.tototoshi.slick.JodaSupport._支持LocalDate转换.在插入和提取Photo对象时,效果也很好.

I also import com.github.tototoshi.slick.JodaSupport._ to support the LocalDate conversion. That also works just fine when inserting and fetching Photo objects.

有什么想法吗?也许某种更好的查询机制可以满足我的需求(枚举相等,日期比较和rand()排序)?谢谢.

Any ideas? Perhaps some sort of better query mechanism to support what I need (enum equality, date comparison, and rand() ordering)? Thanks.

更新日期:2013-10-27

我现在正在尝试以下操作,但是没有运气:

I am now trying to do the following, with no luck:

def recordGuess(date: LocalDate, correctBlah: Blah, incorrectBlah: Blah, isCorrect: Boolean)(implicit s: Session) {
  val correctIncrement = if(isCorrect) 1L else 0L
  sqlu"insert into stats (date, correctBlah, incorrectBlah, impressions, guesses, correct) values ($date, $correctBlah, $incorrectBlah, 1, 1, $correctIncrement) on duplicate key update guesses = guesses + 1, correct = correct + $correctIncrement".first
}

再次,这不起作用:

could not find implicit value for parameter pconv: scala.slick.jdbc.SetParameter[(org.joda.time.LocalDate, models.Blah.Blah, models.Blah.Blah)]

但是,这次我看不到任何简单易行的方法.看起来像Typesafe的sqlsqlu并不支持隐式转换.

However, this time I see no good, easy way around it. Seems like Typesafe's sql and sqlu in slick don't support implicit conversions.

推荐答案

我无法找到隐式转换问题的解决方案,但是我已经找到了使用更传统的平滑语法(scala.util.Random.shuffle)的解决方法:

I haven't been able to find a solution to the implicit conversion problem, but I've found a workaround using more traditional slick syntax, with scala.util.Random.shuffle:

def randomByBlahAndDate(blah: Blah, newerThan: LocalDate)(implicit s: Session): Option[Photo] = {
  val photos = Query(Photos).where(_.imgDate > newerThan).where(_.blah === blah).run
  val r = new scala.util.Random(scala.compat.Platform.currentTime)
  r.shuffle(photos).headOption
}

与使用MySQL的rand()相比,我不确定效率,但这暂时还是可行的.

I'm uncertain about the efficiency compared to using MySQL's rand(), but this will work for the time being.

这篇关于Scala Slick在原始SQL查询中隐式转换多种类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆