【问题标题】:Joins in Grails Criteria加入 Grails 标准
【发布时间】:2016-01-13 18:41:30
【问题描述】:

我正在尝试在 grails 中为以下域编写条件查询:

class Data {
    Long createdById // this is user id
    // other fields
}
class User {
   Company company
   // other fields
}

现在数据,顾名思义就是存储一些数据。它与用户没有直接关系,但有一个字段 createdById 是用户的 id。
(我无法直接引用数据中的用户,因为它们属于不同的项目,其中数据来自自定义可重用插件。)

现在我想在数据上编写标准并列出由给定公司的用户创建的所有记录。那是data.id == User.id and user.company == givenCompany

【问题讨论】:

  • 我认为您必须将两个 GORM 对象与关系联系起来,才能使用标准来做到这一点。连接要求您定义对象之间的一对一或一对多关系 (grails.github.io/grails-doc/3.0.x/guide/…) 定义后,您可以在其中一个或另一个对象上创建条件。

标签: grails grails-orm grails-domain-class


【解决方案1】:

为了使用任何 GORM/Hibernate 查询方法(条件、位置或 HQL),您需要域类之间的关联。由于您无法从DataUser 进行关联,因此您不能使用 GORM 来编写带有域类的查询。换句话说,你需要使用 SQL; HQL(DomainClass.executeQuery() 不起作用)。但是……

使用 HQL

如果你愿意修改User并维护一些冗余数据,你可以使用HQL。

class User {
   Company company
   // other fields

   /* Add uni-directional one-to-many */
   static hasMany = [data: Data]
}

def data = AnyDomainClass.executeQuery('SELECT d FROM User as u INNER JOIN u.data AS d WHERE u.company = :company', [company: givenCompany])

单向一对多关联创建一个连接表,需要维护该连接表以反映Data.createdById。 HQL 连接语法暗示了需要关联的事实。如果必须使用条件查询...

有条件查询

要使用条件查询,您需要修改 User 并添加一个额外的域类。原因是条件查询不能投射 像 HQL 那样的关联。例如,这将工作:

def data = User.withCriteria {
    eq('company', givenCompany)

    projections {
        property('data')
    }
}

由于无法修改 Data,这 -- 这是最简单的解决方案 -- 也将工作:

def data = Data.withCriteria {
    user {
        eq('company', givenCompany)
    }
}

因此,您需要一个中间人来投射 Data 实例:

class User {
   Company company
   // other fields

   static hasMany = [userData: UserData]
}

class UserData {
    Data data

    static belongsTo = [user: User]
}

def data = User.withCriteria {
    eq('company', givenCompany)

    projections {
        userData {
            property('data')
        }
    }
}

可以想象,这种方法也需要一些数据维护。

使用 SQL

最后,您可以选择使用 SQL 并让查询返回域类实例。归根结底是这样的:

AnyDomainClass.withNewSession { session ->
    def data = session.createSQLQuery('SQL GOES HERE').addEntity(Data).list()
}

更多信息

有关更多信息,请查看我的以下文章:

  1. Domain class associations and how they work on the DB level
  2. Joining domain classes with GORM queries
  3. Using SQL and returning domain class instances1 月 22 日上市。

【讨论】:

    【解决方案2】:

    如果您能够为此创建 sql 查询并且无法为此创建条件,那么您可以查找 executeQuery

    我希望它应该工作

    【讨论】:

    • 感谢您的回答,是的,我已经为它编写了一个查询来达到目的,但是应该有一种方法可以使用 grails 标准来做到这一点......我想学习和使用它。
    猜你喜欢
    • 2011-12-08
    • 1970-01-01
    • 1970-01-01
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多