如何在Grails中延迟加载关联时修改Hibernate生成的SQL?

时间:2015-10-19 15:55:38

标签: hibernate grails

我在Oracle数据库中有三个具有以下关联的表:

公司,用户,设置 一家公司有很多用户 一个用户有很多设置 设置有一个引用公司的外键(换句话说,一个公司有很多设置) “设置”表由“公司”分区,并在“用户”上有索引。

我正在尝试让Hibernate生成一个查询来懒洋洋地加载用户的设置,同时通过在查询中包含公司来利用分区。目前,编写以下Grails代码:

def settings = user.settings

产生以下(简化)查询:

SELECT * FROM SETTINGS WHERE USER_ID=user.id

我想在调用上面的Grails代码时生成以下查询:

SELECT * FROM SETTINGS WHERE USER_ID=user.id AND COMPANY_ID=company.id

另外,根据我的理解,在延迟加载集合之后,然后将具体的初始化集合附加到关联对象,并进一步调用该集合,然后从内存中检索集合,而不是运行另一个查询。这很重要,因为我将在不同的流程中多次调用user.settings,所以我正在寻找一个可以做同样的解决方案。

是否可以在不对源代码进行任何重大更改的情况下执行此操作?

2 个答案:

答案 0 :(得分:0)

您可以通过GORM查询获得您正在寻找的内容。我假设Setting没有belongsTo User,这会让事情变得复杂一些。在这种情况下,最合适的是HQL。

def settings = Setting.executeQuery 'select s from User as u inner join u.settings as s inner join s.company as c where u = :user and c = :company', [user: someUser, company: someCompany]

引用用户

如果Setting确实有User的反向引用,那么您可以使用简单的条件或查询。

标准

def settings = Setting.withCriteria {
    eq 'user', someUser
    eq 'company', someCompany
}

其中

def settings = Setting.where {
    user == someUser
    company == someCompany
}

HQL

到底是什么,这是等效的HQL。

def settings = Setting.findAll 'from Setting where user = :user and company = :company', [user: someUser, company: someCompany]

答案 1 :(得分:0)

好像你想在hibernate查询中追加一个过滤器,其中公司id条件会自动附加。

为此你可以使用grails hibernate filter插件。我大约4年前使用过这个插件,不知道它现在是如何工作的https://grails.org/plugin/hibernate-filter