如何在hibernate中使用listagg

时间:2014-05-14 22:32:47

标签: sql hibernate oracle11g

我正在尝试使用listagg函数来生成用户列表。

考虑下表

 ROLE_ID    ENAME
---------- ----------
       4    CLARK
       4    KING
       4    MILLER
       7    ADAMS
       9    FORD
       9    JONES

在SQL Developer中使用以下查询

SELECT ROLE_ID,
       LISTAGG(ENAME, ',') WITHIN GROUP (ORDER BY ENAME) AS EMPLOYEES 
FROM USERS 
GROUP BY ROLE_ID;

将导致控制台输出中的以下内容

ROLE_ID EMPLOYEES
-----------------------------
4        CLARK,KING,MILLER
7        ADAMS
9        FORD, JONES

我的目标是尝试在休眠中执行此操作,但我不确定如何继续。 任何帮助表示赞赏。

6 个答案:

答案 0 :(得分:5)

对于任何使用listagg作为公式的一部分而遇到问题的人,请在"内注册" Hibernate的关键字为我解决了这个问题。 (使用Hibernate 5.0.7。)

public class CustomOracleDialect extends Oracle10gDialect {
    public CustomOracleDialect() {
        super();

        registerKeyword("within");
    }
}

在此之前,Hibernate会通过尝试在"内加上前缀来打破查询。带有外表的别名的关键字。注册关键字后,以下工作:

@Formula("(select (listagg(l.serial_number, ', ') within group(order by d.serial_number))\n"
        + "from order_lines l\n"
        + "where l.order_id = id\n"
        + "group by l.order_id)")
private String serialNumbers;

请注意,如果您尝试为listagg表达式指定别名,它仍然会破坏查询,因为Hibernate也会尝试将其添加到表的别名中。这当然不是公式查询的问题,但如果使用listagg作为命名查询的一部分,您可能需要省略别名并在结果集中按位置引用列。

答案 1 :(得分:0)

Hibernate不明白sql函数是默认的。尝试在hibernateDialect中注册。

registerFunction("listAgg", new StandardSQLFunction("listAgg", Hibernate.STRING));

答案 2 :(得分:0)

注册listagg方法在hibernate方言中不起作用。尝试注册wm_concat方法,它对我有用..

查找以下代码..

<!--                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop> -->
                <prop key="hibernate.dialect">com.apple.sc.analytics.utils.ServiceAppOracle10gDialect</prop>

确保你已经改变了你的hibernate.dialect属性..

{{1}}

答案 3 :(得分:0)

我们找到了一个很好的解决方案。

@Formula("(select (listagg(l.serial_number, ', ') \00within group(order by d.serial_number))\n"
    + "from order_lines l\n"
    + "where l.order_id = id\n"
    + "group by l.order_id)")
private String serialNumbers;

只需在WITHIN关键字前附加\ 00即可。 而且你不需要扩展任何东西。

干杯。

答案 4 :(得分:0)

经过很多努力,我找到了解决方案。我认为这对您有帮助。您可以像下面一样注册LISTAGG功能

registerFunction("LISTAGG", new SQLFunctionTemplate( StandardBasicTypes.STRING,"LISTAGG(?1,',') WITHIN GROUP(ORDER BY ?1)"));

您可以在休眠查询中使用LISTAGG(<columnname>)

答案 5 :(得分:0)

要在休眠查询中使用listagg

  1. 通过扩展Oracle10gDialect(如果使用Oracle)或MySQLDialect(对于MySQL),在Hibernate方言中首先注册listagg函数

public class CustomOracle10gDialect extends Oracle10gDialect { public CustomOracle10gDialect() { super(); registerFunction("LISTAGG", new SQLFunctionTemplate(StandardBasicTypes.STRING,"LISTAGG(?1,',') WITHIN GROUP(ORDER BY ?1)")); } }

  1. 更新您的配置文件以使用自定义方言。 spring.jpa.database-platform = com.abc.CustomOracle10gDialect 要么 com.abc.CustomOracle10gDialect

  2. 使用LISTAGG() 范例- 选择联系人c中的c.id,listagg(firstName),其中GROUP BY c.id