加入 Grails 标准
Joins in Grails Criteria
我正尝试在 grails 中为以下域编写条件查询:
class Data {
Long createdById // this is user id
// other fields
}
class User {
Company company
// other fields
}
现在data,顾名思义就是存储一些数据。它与用户没有直接关系,但有一个字段 createdById,它是用户的 ID。
(我不能在数据中直接引用用户,因为它们属于不同的项目,其中数据来自自定义可重用插件。)
现在我想编写数据标准并列出由给定公司的用户创建的所有记录。即 data.id == User.id and user.company == givenCompany
如果您能够为此创建 sql 查询但无法为此创建条件,那么您可以查找 executeQuery
我希望它能奏效
为了使用任何 GORM/Hibernate 查询方法(标准、where 或 HQL),您需要域 classes 之间的关联。由于您无法建立从 Data
到 User
的关联,因此您无法使用 GORM 编写包含您的域的查询 class 是的。换句话说,你需要使用 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])
uni-directional one-to-many 关联创建了一个连接 table,需要对其进行维护以反映 Data.createdById
。 HQL 连接语法暗示了关联是必需的这一事实。如果您必须使用条件查询...
带条件查询
要使用条件查询,您需要修改 User
并添加一个额外的域 class。原因是标准查询不能 project 像 HQL 那样的关联。例如,这将 not 起作用:
def data = User.withCriteria {
eq('company', givenCompany)
projections {
property('data')
}
}
由于无法修改 Data
,这个——这是最简单的解决方案——也将不工作:
def data = Data.withCriteria {
user {
eq('company', givenCompany)
}
}
因此,您需要 middle-man 才能投射 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 和查询 return 域 class 实例。它归结为这样的事情:
AnyDomainClass.withNewSession { session ->
def data = session.createSQLQuery('SQL GOES HERE').addEntity(Data).list()
}
更多信息
有关更多信息,请查看我的以下文章:
我正尝试在 grails 中为以下域编写条件查询:
class Data {
Long createdById // this is user id
// other fields
}
class User {
Company company
// other fields
}
现在data,顾名思义就是存储一些数据。它与用户没有直接关系,但有一个字段 createdById,它是用户的 ID。
(我不能在数据中直接引用用户,因为它们属于不同的项目,其中数据来自自定义可重用插件。)
现在我想编写数据标准并列出由给定公司的用户创建的所有记录。即 data.id == User.id and user.company == givenCompany
如果您能够为此创建 sql 查询但无法为此创建条件,那么您可以查找 executeQuery
我希望它能奏效
为了使用任何 GORM/Hibernate 查询方法(标准、where 或 HQL),您需要域 classes 之间的关联。由于您无法建立从 Data
到 User
的关联,因此您无法使用 GORM 编写包含您的域的查询 class 是的。换句话说,你需要使用 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])
uni-directional one-to-many 关联创建了一个连接 table,需要对其进行维护以反映 Data.createdById
。 HQL 连接语法暗示了关联是必需的这一事实。如果您必须使用条件查询...
带条件查询
要使用条件查询,您需要修改 User
并添加一个额外的域 class。原因是标准查询不能 project 像 HQL 那样的关联。例如,这将 not 起作用:
def data = User.withCriteria {
eq('company', givenCompany)
projections {
property('data')
}
}
由于无法修改 Data
,这个——这是最简单的解决方案——也将不工作:
def data = Data.withCriteria {
user {
eq('company', givenCompany)
}
}
因此,您需要 middle-man 才能投射 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 和查询 return 域 class 实例。它归结为这样的事情:
AnyDomainClass.withNewSession { session ->
def data = session.createSQLQuery('SQL GOES HERE').addEntity(Data).list()
}
更多信息
有关更多信息,请查看我的以下文章: