将HQL转换为标准

问题描述:

我在HQL中查询完全有效。但是,我希望将它在“条件”表单中表达出来,该表单更易于阅读和维护。将HQL转换为标准

这是场景:我有工人,人员和付款。工人是一个人加上工作类型(在这个应用程序中,一个人可以同时具有不同工作类型的两个工人)。付款有很多,一名工人可能有多个付款。我需要每个工人一次,然后是该工人的所有支付值的总和。这些都是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) 
       } 

它失败:

“MSID”实际上是“身份证”的名字“com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException未知列在‘字段列表’person_ali2_.msid'”字段在数据库中。这是通过在域类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") 
    } 
} 

感谢

+0

from Payment as p * where and * p.month =:m relly这在HQL中有效吗? – 2011-04-05 20:53:32

+0

您能否为付款,工作人员和人员提供域对象?这将有助于我们更好地了解细节。 – 2011-04-06 03:09:33

+0

Pollano,对不起。代码不是英文的,所以我把它放在这里,然后翻译变量名称,这个'和'是一个错字。 – Gabriel 2011-04-06 16:02:17

 def payments = Payment.withCriteria { 
      createAlias('worker','w') 
      projections { 
       property('w.id') 
       groupProperty('w.jobType') 
       groupProperty('w.person')      
      } 
      eq('month', paymentsMonth) 
      eq('year', paymentsYear) 
     } 

上面的查询会给你列出,其中第1个要素是工人的名单,第二个将是jobType,第三个将是已经给出月份和年份的人物对象。

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

谢谢,我不知道这是内部预测的符号。但奇怪的是,查询返回一个整数列表,这是工作人员的工作类型。我试图添加一个属性('工作者')投影,但它失败了,告诉工作人员不映射到单个列。 – Gabriel 2011-04-06 16:23:07

+0

我已经更新了答案,以便在第一个查询中返回工作对象。希望工程? – 2011-04-07 04:36:56

+0

不幸的是,在属性('worker')中,“org.hibernate.QueryException:属性不映射到单个列:worker”失败。我认为这是因为Grails在这种关系中没有正确处理组成ID(在Worker中)。 – Gabriel 2011-04-07 16:14:48