gpt4 book ai didi

java - 使用 Spring JPA 为 STRING_AGG 和 Postgresql 为 Group_By 设置聚合函数

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:23:55 25 4
gpt4 key购买 nike

我正在尝试设置一个 repository 调用来检索 GROUP_BY 中使用的测试结果 ids 列表的 ID。我可以使用 createNativeQuery 让它工作,但我无法使用 Spring 的 JPAFUNCTION 调用让它工作。

FUNCTION('string_agg', FUNCTION('to_char',r.id, '999999999999'), ',')) as ids

我正在使用 Spring Boot 1.4、hibernate 和 PostgreSQL。

问题

  1. 如果有人可以帮我设置正确的函数调用在下面的 JPA 示例中显示,我们将不胜感激。

更新 1

在实现自定义方言后,它看起来像是在尝试将函数转换为 long。函数代码是否正确?

FUNCTION('string_agg', FUNCTION('to_char',r.id, '999999999999'), ','))

更新 2

进一步研究方言后,您似乎需要为函数注册返回类型,否则它将默认为 long。请参阅下面的解决方案。

这是我的代码:

数据传输

    @Data
@NoArgsConstructor
@AllArgsConstructor
public class TestScriptErrorAnalysisDto {
private String testScriptName;
private String testScriptVersion;
private String checkpointName;
private String actionName;
private String errorMessage;
private Long count;
private String testResultIds;
}

Controller

@RequestMapping(method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<Set<TestScriptErrorAnalysisDto>> getTestScriptErrorsByExecutionId(@RequestParam("executionId") Long executionId) throws Exception {

return new ResponseEntity<Set<TestScriptErrorAnalysisDto>>(testScriptErrorAnalysisRepository.findTestScriptErrorsByExecutionId(executionId), HttpStatus.OK);
}

尝试使用函数的存储库不工作

    @Query(value = "SELECT new com.dto.TestScriptErrorAnalysisDto(r.testScriptName, r.testScriptVersion, c.name, ac.name, ac.errorMessage, count(*) as ec, FUNCTION('string_agg', FUNCTION('to_char',r.id, '999999999999'), ',')) "
+ "FROM Action ac, Checkpoint c, TestResult r " + "WHERE ac.status = 'Failed' " + "AND ac.checkpoint = c.id " + "AND r.id = c.testResult " + "AND r.testRunExecutionLogId = :executionId "
+ "GROUP by r.testScriptName, r.testScriptVersion, c.name, ac.name, ac.errorMessage " + "ORDER by ec desc")
Set<TestScriptErrorAnalysisDto> findTestScriptErrorsByExecutionId(@Param("executionId") Long executionId);

使用 createNativeQuery 的存储库有效

    List<Object[]> errorObjects = entityManager.createNativeQuery(
"SELECT r.test_script_name, r.test_script_version, c.name as checkpoint_name, ac.name as action_name, ac.error_message, count(*) as ec, string_agg(to_char(r.id, '999999999999'), ',') as test_result_ids "
+ "FROM action ac, checkpoint c, test_result r " + "WHERE ac.status = 'Failed' " + "AND ac.checkpoint_id = c.id "
+ "AND r.id = c.test_result_id " + "AND r.test_run_execution_log_id = ? "
+ "GROUP by r.test_script_name, r.test_script_version, c.name, ac.name, ac.error_message " + "ORDER by ec desc")
.setParameter(1, test_run_execution_log_id).getResultList();

for (Object[] obj : errorObjects) {
for (Object ind : obj) {
log.debug("Value: " + ind.toString());
log.debug("Value: " + ind.getClass());
}
}

这是我在 FUNCTION 上找到的文档

            4.6.17.3 Invocation of Predefined and User-defined Database Functions

The invocation of functions other than the built-in functions of the Java Persistence query language is supported by means of the function_invocation syntax. This includes the invocation of predefined database functions and user-defined database functions.

function_invocation::= FUNCTION(function_name {, function_arg}*)
function_arg ::=
literal |
state_valued_path_expression |
input_parameter |
scalar_expression
The function_name argument is a string that denotes the database function that is to be invoked. The arguments must be suitable for the database function that is to be invoked. The result of the function must be suitable for the invocation context.

The function may be a database-defined function or a user-defined function. The function may be a scalar function or an aggregate function.

Applications that use the function_invocation syntax will not be portable across databases.

Example:

SELECT c
FROM Customer c
WHERE FUNCTION(‘hasGoodCredit’, c.balance, c.creditLimit)

最佳答案

最后缺少的主要部分是通过创建一个新类来扩展 PostgreSQL94Dialect 来定义函数。由于这些函数不是为方言定义的,因此它们不会在调用中处理。

    public class MCBPostgreSQL9Dialect extends PostgreSQL94Dialect {

public MCBPostgreSQL9Dialect() {
super();
registerFunction("string_agg", new StandardSQLFunction("string_agg", new org.hibernate.type.StringType()));
registerFunction("to_char", new StandardSQLFunction("to_char"));
registerFunction("trim", new StandardSQLFunction("trim"));
}
}

另一个问题是需要在注册时为函数的返回类型设置一个类型。我得到了一个 long 返回,因为默认情况下 registerFunction 返回一个 long,即使 string_agg 会在 postgres 的 sql 查询中返回一个字符串。

在用 new org.hibernate.type.StringType() 更新后它起作用了。

            registerFunction("string_agg", new StandardSQLFunction("string_agg", new org.hibernate.type.StringType()));

关于java - 使用 Spring JPA 为 STRING_AGG 和 Postgresql 为 Group_By 设置聚合函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47878811/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com