问题
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.
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
}
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)]
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)
I also import com.github.tototoshi.slick.JodaSupport._
to support the LocalDate
conversion. That also works just fine when inserting and fetching Photo
objects.
Any ideas? Perhaps some sort of better query mechanism to support what I need (enum equality, date comparison, and rand() ordering)? Thanks.
UPDATE: 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
}
Which again, doesn't work:
could not find implicit value for parameter pconv: scala.slick.jdbc.SetParameter[(org.joda.time.LocalDate, models.Blah.Blah, models.Blah.Blah)]
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.
回答1:
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
}
I'm uncertain about the efficiency compared to using MySQL's rand()
, but this will work for the time being.
来源:https://stackoverflow.com/questions/19535120/scala-slick-implicit-conversion-of-multiple-types-in-raw-sql-query