假设我有一个类似的实体类:
case class MyEntity(some_flag: Boolean) extends KeyedEntity[Long]
我想使用Squeryl执行以下SQL更新:
update table_name set some_flag = not some_flag where id = 1
相关的Squeryl声明是做什么的?我已经尝试过了
def toggleFlag(id: Long) = inTransaction {
update(table)(entity =>
where(entity.id === id)
set(entity.some_flag := !entity.some_flag)
)
}
但这对数据库没有任何影响。
更新2: Squeryl documentation给出了部分更新示例,将整数值增加1:
update(songs)(s =>
where(s.title === "Watermelon Man")
set(s.title := "The Watermelon Man",
s.year := s.year.~ + 1)
)
更新
我正在使用Squeryl 0.9.5-6与Scala 2.10和Play! 2.1
答案 0 :(得分:1)
我从你的例子中做了一个小代码项目。问题是squeryl序列化了更新,但是它“吞下”了(!),产生了以下SQL:
update MyEntity set
some_flag = (some_flag)
基本上,squeryl在操作系统构建的树下构建,然后将其序列化为将发送到SQL适配器的字符串。
一般情况下,我检查它是否隔离更新语句并打印它(如squeryl那样):
// From __update, Table.scala
val dba = Session.currentSession.databaseAdapter
val sw = new StatementWriter(dba)
val o0 = _callbacks.beforeUpdate(o.asInstanceOf[AnyRef]).asInstanceOf[T]
dba.writeUpdate(o0, this, sw, checkOCC)
复制我的类中的代码(用于调试目的)或直接在Table.scala中设置断点
要隔离语句,只需考虑更新的第二部分:
val s = ((entity: InsertTypeHere) =>
where(entity.id === id)
set(entity.some_flag := not entity.some_flag))
由于这个“技巧”,我发现对some_flag的引用被正确转换为类型为java.lang.Boolean的SelectElementReference,但是(!)没有被转换为PrefixOperator。这对我来说似乎是一个squeryl bug,但让我看看是否可以从你的代码中“修复”它。
更新:
挖掘squeryl代码,似乎缺少“not”运算符。幸运的是,很容易自己添加它!
class NotExpression(val ast: ExpressionNode)(implicit val mapper: OutMapper[BooleanType])
extends PrefixOperatorNode(ast, "not ", false)
with LogicalBoolean with NestedExpression with TypedExpressionNode[BooleanType]
def mynot(b: BooleanExpression[BooleanType]) = new NotExpression(b)
transaction {
update(table)(t => where(t.id === 3) set (t.some_flag := mynot(t.some_flag)))
}
这会生成正确的SQL,至少在您的情况下如此。我会向squeryl提交补丁并征求意见。