我需要通过REST接口执行一些可能依赖于外部提供的参数的查询。例如,客户可能需要表格
的URLsome/entities?foo=12&bar=17
参数,例如foo
,bar
和quux
都是可选的。所以我从使用Squeryl设计一些查询开始,比如
object Entity {
def byFoo(id: Long) = from(DB.entities)(e =>
where(e.foo === id)
select(e)
)
// more criteria
}
但是我当然希望避免出现组合爆炸,所以我只设计了三个查询,而这些查询又可以从另一个查询中获取数据:
object Entity {
def byFoo(id: Long, source: Query[Entity] = DB.entites) = from(source)(e =>
where(e.foo === id)
select(e)
)
def byBar(id: Long, source: Query[Entity] = DB.entites) = from(source)(e =>
where(e.bar === id)
select(e)
)
// more criteria
}
现在我可以将它们组合起来并运行像
这样的查询val result = Entity.byFoo(12,
source = Entity.byBar(17)
)
我采用这种方法的唯一问题是幕后的Squeryl将生成子查询,这可能是低效的。使用更典型的查询构建器,我将能够组合查询并获得以下内容的等效项:
from(DB.entities)(e =>
where(
e.foo === 12 and
e.bar === 17
)
select(e)
)
是否有一种不同的方法可以动态组合Squeryl中的查询,从而形成更高效的表单?
答案 0 :(得分:2)
我认为你应该考虑的第一件事就是抑制,你可以找到in the documentation。它的要点是您为查询建模,如:
var foo: Option[Int] = None
var bar: Option[Int] = None
from(DB.entities)(e =>
where(
e.foo === foo.? and
e.bar === bar.?)
select(e))
?第一个表达式中的运算符等价于(e.foo === foo).inhibitWhen(foo == None)