加入圣杯标准



我正在尝试用grails为以下域编写标准查询:

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

现在,顾名思义,数据存储了一些数据。它与用户没有直接关系,但有一个字段创建ById,它是用户的ID。
(我不能直接引用数据中的用户,因为这些属于不同的项目,其中数据来自自定义的可重用插件。

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

为了使用任何 GORM/Hibernate 查询方法(criteria、where 或 HQL),您需要在域类之间进行关联。由于您无法从Data关联到User,因此无法使用 GORM 使用域类编写查询。换句话说,您需要使用 SQL;HQL(DomainClass.executeQuery()将不起作用)。但。。。

与总部

如果您愿意修改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 并让查询返回域类实例。它归结为这样:

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

更多信息

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

  1. 域类关联及其在数据库级别的工作方式
  2. 使用 GORM 查询联接域类
  3. 使用 SQL 并返回域类实例。1月22日发售。

如果您能够为此创建sql查询,但无法为此创建条件,则可以查找executeQuery

我希望它应该有效

最新更新