将 HQL 转换为标准

发布于 2024-10-31 01:50:49 字数 2344 浏览 1 评论 0原文

我在 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:‘字段列表’中的未知列‘person_ali2_.msid’”

‘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")
    }
}

谢谢

I have a query in HQL which fully works. However, I'd like to have it expressed in the Criteria form, which is easier to read and maintain.

This is the scenario: I have Workers, People and Payments. A worker is a Person plus a Job Type (one person, in this app, can be two workers with distinct Job Types at the same time). There are many Payments, and there might be more than one for one worker. I need to get each worker one time, and then the sum of all the Payment values for that worker. These are the HQL Queries:

1- Get all payments:

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- Iterating through the Payments, for each one I get the sum of the Payments for that worker this way (it is the payment):

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()

It works, but not the Criteria I tried to write to replace it:

1-

def payments = Payment.withCriteria {
                    worker {

                        projections {
                            groupProperty('jobType')
                        }

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

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

It fails with "com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'person_ali2_.msid' in 'field list'"

'msid' is actually the name of the 'id' field in the database. That's done via mapping id in the domain class Worker.

Do you see any new possibilities?

Thanks

Update:

We need to use legacy databases, provided by the client. For better organization, the classes we use from them are represented as views, named "legacy_tablename", and everything that is exclusively inside our part of the system is in a separate database, so the views reference tables in other databases and we don't need to treat multiple databases inside the code. So that's why sometimes table names are specified.

The domain classes are big, but these are the important details about them:

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")
    }
}

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

属性 2024-11-07 01:50:52
      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)
        }
      def payments = Payment.withCriteria {
           createAlias('worker','w')
           projections {
               property('w.id')  
               groupProperty('w.jobType')
               groupProperty('w.person')                       
            }
            eq('month', paymentsMonth)
            eq('year', paymentsYear)
        }

Above query would give you list of lists, where 1st element would be worker, 2nd would be jobType and 3rd would be person object which has given month and year.

  def payments = Payment.withCriteria {
            projections {
             sum('liquidValue')
            }   
            eq('month', paymentsMonth)
            eq('year', paymentsYear)
            eq('worker',worker)
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文