grails - 加入 Grails 标准

标签 grails grails-orm grails-domain-class

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

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

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

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

最佳答案

为了使用任何 GORM/Hibernate 查询方法(标准、where 或 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])

单向一对多关联创建一个连接表,需要对其进行维护以反射(reflect) 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 instances . 1 月 22 日可用。

关于grails - 加入 Grails 标准,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34774578/

相关文章:

hibernate - 使用Hibernate/GORM导致java.sql.BatchUpdateException错误

grails - Grails没有将DataSource.groovy文件用于测试环境

database - 具有链式调用的 Grails 服务类的事务行为

grails - 无法在 Grails 中创建新的域对象

mysql - grails 域默认按上次更新字段排序

grails - 为什么只读访问在 GORM 中写入我的数据库?

unit-testing - @TestFor 在域的单元测试中做什么?

grails - Grails多对一的暴露id而没有延迟加载?

java - 重载 Grails 静态 'mapping' 属性来固定数据库对象是否违反了 DRY?

grails - 没有依赖删除的 GORM 关系