【发布时间】:2014-12-19 09:00:47
【问题描述】:
我遇到了可空列比较的问题。
如果某些列是Option[T],我想知道如何将这些列上的=== 操作转换为sql。
有两种可能性:空值(在 scala 中为 None )和非空值。
在空值的情况下,sql应该使用is而不是=。
但是在以下情况下 slick 无法正确处理它。
这里是代码(带有H2数据库):
object Test1 extends Controller {
case class User(id: Option[Int], first: String, last: String)
class Users(tag: Tag) extends Table[User](tag, "users") {
def id = column[Int]("id",O.Nullable)
def first = column[String]("first")
def last = column[String]("last")
def * = (id.?, first, last) <> (User.tupled, User.unapply)
}
val users = TableQuery[Users]
def find_u(u:User) = DB.db.withSession{ implicit session =>
users.filter( x=> x.id === u.id && x.first === u.first && x.last === u.last ).firstOption
}
def t1 = Action {
DB.db.withSession { implicit session =>
DB.createIfNotExists(users)
val u1 = User(None,"123","abc")
val u2 = User(Some(1232),"123","abc")
users += u1
val r1 = find_u(u1)
println(r1)
val r2 = find_u(u2)
println(r2)
}
Ok("good")
}
}
我打印出 sql。这是第一个find_u 的结果。
[debug] s.s.j.J.statement - Preparing statement: select x2."id", x2."first", x2."last" from "users" x2 where (
(x2."id" = null) and (x2."first" = '123')) and (x2."last" = 'abc')
请注意(x2."id" = null) 此处不正确。应该是(x2."id" is null)。
更新:
是否可以仅以自动方式比较非空字段?忽略那些空列。
例如。对于User(None,"123","abc"),只做where (x2."first" = '123')) and (x2."last" = 'abc')
【问题讨论】:
-
不要使用列[Int]("id",O.Nullable)。正确的是 column[Option[Int]]("id")。否则你可能会遇到异常。
-
嗨@cvogt,谢谢你的建议。但是 column[Option[Int]]("id") 不能解决我的问题。 sql 保持不变。
-
没错,这就是为什么我也写了一个答案:)