简体   繁体   English

如何将 listagg 与 querydsl 一起使用?

[英]How to use listagg with querydsl?

I have a query as shown below;我有一个查询,如下所示;

SELECT 
   .
   .
   LISTAGG(DISTINCT CC.POPULATION, ', ') WITHIN GROUP (ORDER BY CC.POPULATION ASC),
   .
   .
FROM COUNTRY C
     JOIN CITY CC ON C.ID = CC.COUNTRY_ID
--WHERE 
GROUP BY C.ID;

I should be implement with querydsl for custom filtering and sorting operations but I got "No pattern found for LISTAGG" error我应该使用 querydsl 来实现自定义过滤和排序操作,但我得到“没有为 LISTAGG 找到模式”错误

JPAQuery<Tuple> jpaQuery = jpaQueryFactory.select(         
            SQLExpressions.listagg(QCity.city.POPULATION, ",")
            .withinGroup()
            .orderBy(QCity.city.POPULATION.asc())
    )
            .from(QCountry.country)
            .join(QCity.city).on(QCountry.country.id.eq(QCity.city.countryId))
            //.where(custom filtering)
            .groupBy(QCountry.country.id);

jpaQuery.fetch();

I try to add custom template like this but I couldn't succeed.我尝试添加这样的自定义模板,但我无法成功。 Also my querydsl-sql version is 4.2.1我的 querydsl-sql 版本也是 4.2.1

StringTemplate customPopulationTemplate = Expressions.stringTemplate(
            "(LISTAGG(DISTINCT {0},',') WITHIN GROUP (ORDER BY {0} ASC))", QCity.city.population);

Window functions are not included in the JPQL specification and as such not available in any JPA implementation. Window 函数未包含在 JPQL 规范中,因此在任何 JPA 实现中均不可用。 You could register these functions yourself using custom functions .您可以使用自定义函数自己注册这些函数

However, after this, these functions still won't be accessible in QueryDSL.但是,在此之后,这些功能仍然无法在 QueryDSL 中访问。 You're stealing from the SQLExpressions here to obtain a window expression.您正在从此处的SQLExpressions中窃取 window 表达式。 These methods live in SQLExpressions for a reason: they only work with querydsl-sql and not with querydsl-jpa (again, because JPA itself does not support window functions).这些方法存在于SQLExpressions中是有原因的:它们仅适用于querydsl-sql而不适用于querydsl-jpa (同样,因为 JPA 本身不支持 window 函数)。 So after registering your custom function, you will still have to extend JPQLTemplates to include the template for your custom window function.因此,在注册您的自定义 function 后,您仍然需要扩展JPQLTemplates以包含自定义 window function 的模板。

You'd do this like this:你会这样做:

public class MyTemplates extends JPQLTemplates {

    public MyTemplates() {
        add(SQLOps.ROWNUMBER, "ROW_NUMBER({0})");
    }

}

And then use it as follows:然后按如下方式使用它:

new JPAQuery(entityManager, new MyTemplates()).from(entity).select(rowNumber())

Alternatively you could look into the blaze-persistence-querydsl extension, which has out of the box support for window functions (and many other features) for JPQL.或者,您可以查看blaze-persistence-querydsl扩展,它对 JPQL 的 window 功能(和许多其他功能)提供开箱即用的支持。 For example:例如:

QCat cat = QCat.cat;

BlazeJPAQuery<Tuple> query = new BlazeJPAQuery<Tuple>(entityManager, criteriaBuilderFactory).from(cat)
    .select(cat.name, JPQLNextExpressions.rowNumber(), JPQLNextExpressions.lastValue(cat.name).over().partitionBy(cat.id));

List<Tuple> fetch = query.fetch();

Since Hibernate 5.2.18, you can use the MetadataBuilderContributor utility to customize the MetadataBuilder even if you are bootstrapping via JPA.从 Hibernate 5.2.18 开始,即使您通过 JPA 引导,也可以使用 MetadataBuilderContributor 实用程序自定义 MetadataBuilder。

The MetadataBuilderContributor interface can be implemented like this: MetadataBuilderContributor接口可以这样实现:

public class SqlFunctionsMetadataBuilderContributor
    implements MetadataBuilderContributor {
     
 @Override
 public void contribute(MetadataBuilder metadataBuilder) {
    metadataBuilder.applySqlFunction(
        "group_concat",
        new StandardSQLFunction(
            "group_concat",
            StandardBasicTypes.STRING
        )
    );
 }
}

And, we can provide the SqlFunctionsMetadataBuilderContributor via the hibernate.metadata_builder_contributor configuration property:而且,我们可以通过 hibernate.metadata_builder_contributor 配置属性提供 SqlFunctionsMetadataBuilderContributor:

<property>
    name="hibernate.metadata_builder_contributor"
    value="com.vladmihalcea.book.hpjp.hibernate.query.function.SqlFunctionsMetadataBuilderContributor"
</property>

Reference: https://vladmihalcea.com/hibernate-sql-function-jpql-criteria-api-query/参考: https://vladmihalcea.com/hibernate-sql-function-jpql-criteria-api-query/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM