【问题标题】:Transform HQL into Criteria将 HQL 转换为标准
【发布时间】:2011-07-30 07:44:25
【问题描述】:

我在 HQL 中有一个完全有效的查询。但是,我希望它以 Criteria 形式表示,这样更易​​于阅读和维护。

这是场景:我有工人、人员和付款。一个工人是一个人加上一个工作类型(在这个应用程序中,一个人可以同时是两个具有不同工作类型的工人)。有许多付款,并且可能不止一个工人的付款。我需要让每个工人一次,然后是该工人的所有付款值的总和。这些是 HQL 查询:

1- 获得所有付款:

Payment.findAll("from Payment as p where p.month = :m and p.year = :y group by p.worker.id, p.worker.person.id", [m: paymentsMonth, y: paymentsYear])

2- 遍历付款,对于每一个我以这种方式获得该工人的付款总和(这是付款):

def totalLiquidValue = Payment.executeQuery('''select sum(liquidValue) from Payment where
                                                month = :m and
                                                year = :ar and
                                                worker = :w''',
                                                [m: it.paymentMonth, ar: it.year, w: payment.worker])
                                                .first()

它有效,但不是我尝试编写的替换它的标准:

1-

def payments = Payment.withCriteria {
                    worker {

                        projections {
                            groupProperty('jobType')
                        }

                        person {
                            projections {
                                groupProperty('id')
                            }
                        }
                    }

                    eq('month', paymentsMonth)
                    eq('year', paymentsYear)
                }

失败并显示“com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'person_ali2_.msid' in 'field list'”

'msid' 实际上是数据库中'id' 字段的名称。这是通过在域类 Worker 中映射 id 来完成的。

您是否看到了任何新的可能性?

谢谢

更新:

我们需要使用客户端提供的遗留数据库。为了更好地组织,我们从中使用的类表示为视图,命名为“legacy_tablename”,并且仅在我们系统部分内部的所有内容都在单独的数据库中,因此视图引用其他数据库中的表而我们不需要在代码中处理多个数据库。这就是为什么有时会指定表名的原因。

领域类很大,但这些是关于它们的重要细节:

class Payment{

    Integer year
    Integer month

    Worker worker

    BigDecimal liquidValue

}

class Worker {
    Person person
    Integer jobType

    static mapping = {
      table("legacy_worker")
      id(composite: ["jobType", "person"])
      person(column: "msid", fetch: "join")
    }     
}

class Person {
    String id

    static mapping = {
       table("legacy_person")
       id(column:"msid", generator: "assigned")
    }
}

谢谢

【问题讨论】:

  • 从 Payment as p where and p.month = :m relly 这在 HQL 中有效吗?
  • 能否提供 Payment、Worker 和 Person 的域对象?这将有助于我们更好地了解细节。
  • 波拉诺,对不起。代码不是英文的,所以我把它放在这里然后翻译变量名,这个“和”是一个错字。

标签: hibernate grails hql criteria


【解决方案1】:
      def payments = Payment.withCriteria {
           createAlias('worker','w')
           projections {
               property('w.id')  
               groupProperty('w.jobType')
               groupProperty('w.person')                       
            }
            eq('month', paymentsMonth)
            eq('year', paymentsYear)
        }

上面的查询会给你一个列表,其中第一个元素是工人,第二个是jobType,第三个是给定月份和年份的人对象。

  def payments = Payment.withCriteria {
            projections {
             sum('liquidValue')
            }   
            eq('month', paymentsMonth)
            eq('year', paymentsYear)
            eq('worker',worker)
        }

【讨论】:

  • 谢谢,我不知道这是内部投影的符号。但是,奇怪的是,查询返回了一个整数列表,它们是 Workers 的 jobTypes。我试图添加一个 property('worker') 投影,但它失败了,告诉 worker 没有映射到单个列。
  • 我已经更新了答案,在第一个查询中返回工作对象。希望这有效吗?
  • 不幸的是,它在属性('worker')中出现“org.hibernate.QueryException:属性未映射到单个列:worker”而失败。我认为这是因为 Grails 没有正确处理这种关系中的组合 id(在 Worker 中)。
猜你喜欢
  • 2014-09-14
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
  • 2014-01-20
  • 2014-12-26
  • 1970-01-01
  • 2011-05-26
相关资源
最近更新 更多