为了使用任何 GORM/Hibernate 查询方法(条件、位置或 HQL),您需要域类之间的关联。由于您无法从Data 到User 进行关联,因此您不能使用 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()
}
更多信息
有关更多信息,请查看我的以下文章:
- Domain class associations and how they work on the DB level
- Joining domain classes with GORM queries
-
Using SQL and returning domain class instances。 1 月 22 日上市。