使用JPA Criteria API,我想按一列分组并连接另一列的值。
例如,下面是sql方法,我正在寻找等效的条件查询(和jpql查询)方法。
mysql> select *from GroupConcatenateDemo;
+------+-------+
| Id | Name |
+------+-------+
| 10 | Larry |
| 11 | Mike |
| 12 | John |
| 10 | Elon |
| 10 | Bob |
| 11 | Sam |
+------+-------+
使用SQL分组
mysql> select Id,group_concat(Name SEPARATOR ',') as GroupConcatDemo from GroupConcatenateDemo group by Id;
+------+-----------------+
| Id | GroupConcatDemo |
+------+-----------------+
| 10 | Larry,Elon,Bob |
| 11 | Mike,Sam |
| 12 | John |
+------+-----------------+
Criteria Query / JPQL是否有group_concat
的等价物,或者是否有其他方法可以实现上述最终输出?
我已经检查并测试了这两个API,它们似乎都只提供concat
函数,这与SQL group_concat
不同。
编辑-
**我知道如何注册一个db函数-**我可以使用Criteria API中的GROUP_CONCAT
函数。为此我必须添加一个自定义方言类并将该类通知spring( Boot )。
package com.mypackage;
import org.hibernate.dialect.MySQL8Dialect;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.type.StandardBasicTypes;
public class CustomMySQLDialect extends MySQL8Dialect {
public CustomMySQLDialect() {
super();
registerFunction(
"GROUP_CONCAT",
new StandardSQLFunction(
"GROUP_CONCAT",
StandardBasicTypes.STRING
)
);
}
}
,然后在application.properties中将该类通知给 Boot 。spring.jpa.properties.hibernate.dialect = com.mypackage.CustomMySQLDialect
虽然它的工作,但与问题-
1.我不知道如何使用SEPERATOR
,我想使用一个分隔符,而不是默认的,
(逗号)。
1.我还想使用group_concat的DISTINCT
、ORDER BY
特性。
我如何通过标准api传递这些。
现状-。
- 目前我的条件查询的
group_concat
代码部分如下所示 * -
some other selects... , cb.function("GROUP_CONCAT", String.class, packagesJoin.get("packageName")), some other selects
- 并且生成的sql部分是 * -
GROUP_CONCAT(packages4_.package_name) as col_3_0_,
。 - 输出为 * -
Package-1,Package-1,Package-2,Package-2
SOF建议的情况-
就像@jens-schauder建议的那样(谢谢jens)-如果我使用
函数(“group_concat”,字符串.类,cb.concat(根.get(“名称”),cb.literal(“,”))
- 即代码为 *
cb.function("GROUP_CONCAT", String.class, packagesJoin.get("packageName"), cb.literal(",")),
- 生成的sql为-*
GROUP_CONCAT(packages4_.package_name,
',') as col_3_0_,
- 输出为:*
Package-1,,Package-1,,Package-2,,Package-2,
- 此方法中的问题是-
cb.literal(",")
中的,
与列值串联在一起。这种情况不应发生,应予以解决。*
**所需/所需的情况-**我要生成的SQL是-
GROUP_CONCAT(DISTINCT packages4_.package_name ORDER BY packages4_.package_name DESC SEPARATOR ' # ') as col_3_0_,
.
- 所需输出为 *
Package-2 # Package-1
我还应该添加什么到条件查询。任何答案都将非常感谢....这对我来说是相当关键的。
2条答案
按热度按时间yqkkidmi1#
解决方案之一是创建一个自定义的
GROUP_CONCAT
HQL函数,该函数将被转换为SQL。创意是创造功能:
group_concat(name, true, ' # ', name, 'DESC')
个它们正在翻译:
GROUP_CONCAT(DISTINCT name ORDER BY name DESC SEPARATOR ' # ' )
**请注意:**实现并不处理
GROUP_CONCAT
函数的所有可能用例,例如,不处理限制参数和用于排序的多个列。但它可以扩展。当前实现完全解决了所描述的问题。1.使用处理DISTINCT/ ORDER BY / SEPARATOR参数的逻辑扩展StandardSQLFunction
2.寄存器GROUP_CONCAT函数
用法示例:
前提条件
第一个
JPQL查询
生成的sql
标准API
生成的sql
输出:
am46iovg2#
可以使用
CriteriaBuilder.function
调用任意SQL函数。我看不出有什么简单的方法来模仿
SEPARATOR ','
语法。你可以做的是在调用group_concat
之前将分隔符附加到字段中。你需要去掉最后一个“,"。This article提到在select子句中使用函数时需要注册该函数。
https://stackoverflow.com/a/52725042/66686中解释了如何执行此操作。它甚至可以允许创建可用于呈现
SEPERATOR
子句的自定义SQL。