1

我需要执行一些可能依赖于通过 REST 接口提供的外部参数的查询。例如,客户端可能需要表单的 URL

some/entities?foo=12&bar=17

foo参数,saybarquux都是可选的。所以我从用 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 中动态组合查询,从而产生这种更有效的形式?

4

1 回答 1

2

我认为您应该研究的第一件事是 inhibitorWhen,您可以在文档中找到它。它的要点是您将查询建模为:

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)

于 2012-11-23T21:45:02.167 回答