我有一个liftweb应用程序,我在其中使用Record / Squeryl作为ORM框架。 这是我的架构:
object AppSchema extends Schema {
import org.squeryl.dsl.OneToManyRelation
val groups = table[Group]("groups")
val domains = table[Domain]("domains")
val groupToDomains =
oneToManyRelation(groups, domains).
via((g, d) => g.id === d.groupId)
}
object Group extends Group with MetaRecord[Group] with Loggable {
}
class Group extends Record[Group] with KeyedRecord[Long] with Loggable {
override def meta = Group
@Column(name = "id") override val idField = new LongField(this)
val name = new StringField(this, 700, "")
@Column(name = "date_added") val createdAt = new DateTimeField(this)
lazy val domains: OneToMany[Domain] = AppSchema.groupToDomains.left(this)
}
object Domain extends Domain with MetaRecord[Domain] with Loggable {
}
class Domain extends Record[Domain] with KeyedRecord[Long] {
override def meta = Domain
@Column(name = "id") override val idField = new LongField(this)
@Column(name = "group_id") val groupId = new LongField(this)
val name = new StringField(this, 700, "")
@Column(name = "date_added") val createdAt = new DateTimeField(this)
lazy val group: ManyToOne[Group] = AppSchema.groupToDomains.right(this)
}
我正在尝试实现一个计算组中域名的函数:
def countDomainsInGroup(group: Group): Long = {
val l = from(AppSchema.domains)(d => where(d.groupId === group.id) compute(count()))
println("Count domains: " + l.statement)
l.single.measures
}
这将生成以下SQL:
Select
count(*) as c0
From
domains domains1
Where
(domains1.group_id = 45)
现在一切都还行,但我想应该有一个捷径,因为我们已经有了group.domains,它有 定义了正确的WHERE语句。但当我尝试使用它时:
def countDomainsInGroup(group: Group): Long = {
val l = from(group.domains)(d => compute(count()))
println("Count domains: " + l.statement)
l.single.measures
}
我得到以下SQL生成:
Select
count(*) as c0
From
(Select
domains8.name as domains8_name,
domains8.id as domains8_id,
domains8.group_id as domains8_group_id,
domains8.date_added as domains8_date_added,
From
domains domains8
Where
(45 = domains8.group_id)
) q1
如您所见,这里生成了一个子查询,我不需要它。我做错了什么?
答案 0 :(得分:0)
如果仔细查看OneToMany / ManyToOne,您会看到它们扩展了Query。它们基本上便于执行查询,该查询通过主键检索与父或子相关的所有对象。如果你这样看,你看到的SQL就不足为奇了。您要求查询结果的计数,并且Squeryl在输出SQL时特意非常直观,以便您可以自己优化事物而不必担心重写。如果子查询不是最优的,则没有理由要计算关系的计数。