Java 使用聚合函数时,NamedParameterJdbcTemplate查询不返回任何内容
在使用postgreSQL的spring启动项目中使用NamedParameterJdbcTemplate时,我遇到了如下情况 我有以下代码Java 使用聚合函数时,NamedParameterJdbcTemplate查询不返回任何内容,java,postgresql,spring-boot,hibernate,Java,Postgresql,Spring Boot,Hibernate,在使用postgreSQL的spring启动项目中使用NamedParameterJdbcTemplate时,我遇到了如下情况 我有以下代码 SalesDto salesDto = new SalesDto(); namedParameterJdbcTemplate.query("SELECT SUM(asts.downloads) AS downloads, SUM(asts.amount_earned) " + "AS earnings
SalesDto salesDto = new SalesDto();
namedParameterJdbcTemplate.query("SELECT SUM(asts.downloads) AS downloads, SUM(asts.amount_earned) " +
"AS earnings FROM t_asset_sale asts", rs -> {
if (rs.next()) {
salesDto.setEarnings(rs.getDouble("earnings"));
salesDto.setDownloads(rs.getInt("downloads"));
}
});
并且收入和下载值不会分配给salesDto对象。我也调试了代码,发现没有执行if语句中的行
但是当我添加一个return语句时
namedParameterJdbcTemplate.query("SELECT SUM(asts.downloads) AS downloads, SUM(asts.amount_earned) " +
"AS earnings FROM t_asset_sale asts", rs -> {
if (rs.next()) {
salesDto.setEarnings(rs.getDouble("earnings"));
salesDto.setDownloads(rs.getInt("downloads"));
}
return salesDto;
});
然后将这些值指定给dto对象。即使我返回一个新对象()
执行内部的行而不是salesDto。那么返回语句的影响是什么呢?我的意思是没有错误;我甚至没有返回语句。有人能解释一下这里发生了什么吗。
我使用的是java 8、postgres 13和spring boot starter父级2.2.4。您正在使用两个参数调用名为
query
的方法,第一个参数是字符串
有3个重载:
由于要将lambda表达式作为第二个参数传递,因此我们需要查看这3个参数的函数接口:
由于lambda表达式只接受1个参数,因此第3个重载将被删除,为编译器留下2个选项:
- 如果没有
return
语句,则只有void
方法有效,因此编译器选择RowCallbackHandler
重载
- 使用
return
语句,编译器可能会失败,并显示“不明确”的错误消息,或者选择ResultSetExtractor
重载。
您的编译器似乎选择了第二个重载
两种方法的Javadoc:
接口RowCallbackHandler
如果需要每行只映射一个结果对象,请考虑使用行映射器,将它们组合到一个列表中
void processRow(ResultSet rs)引发SQLException
实现必须实现此方法来处理结果集中的每一行数据。此方法不应调用ResultSet上的next();它应该只提取当前行的值
接口结果文本采集器
extractData(ResultSet rs)抛出SQLException、DataAccessException
实现必须实现此方法才能处理整个结果集
如果没有return
语句,框架已经调用了next()
,因此当您调用next()
时,它将返回false并跳过代码。使用return
语句,您应该反复调用next()
,直到处理完所有行
使用2个重载的正确方法如下所示,通过对函数接口的强制转换来消除方法重载的模糊性:
String sql=“选择SUM(asts.downloads)作为下载”+
,作为收入的金额+
“来自t_资产销售asts”;
//RowCallbackHandler
SalesDto SalesDto=新的SalesDto();
namedParameterJdbcTemplate.query(sql,(RowCallbackHandler)rs->{
销售收入(rs.getDouble(“收入”));
salesDto.setDownloads(rs.getInt(“下载”);
});
//ResultSetExtractor
SalesDto SalesDto=namedParameterJdbcTemplate.query(sql,(ResultsTextRactor)rs->{
如果(!rs.next())
抛出新的EmptyResultDataAccessException(“聚合查询”,1);
SalesDto SalesDto=新的SalesDto();
销售收入(rs.getDouble(“收入”));
salesDto.setDownloads(rs.getInt(“下载”);
将salesDto退回;
});
您正在使用两个参数调用名为query
的方法,第一个参数是字符串
有3个重载:
由于要将lambda表达式作为第二个参数传递,因此我们需要查看这3个参数的函数接口:
由于lambda表达式只接受1个参数,因此第3个重载将被删除,为编译器留下2个选项:
- 如果没有
return
语句,则只有void
方法有效,因此编译器选择RowCallbackHandler
重载
- 使用
return
语句,编译器可能会失败,并显示“不明确”的错误消息,或者选择ResultSetExtractor
重载。
您的编译器似乎选择了第二个重载
两种方法的Javadoc:
接口RowCallbackHandler
如果需要每行只映射一个结果对象,请考虑使用行映射器,将它们组合到一个列表中
void processRow(ResultSet rs)引发SQLException
实现必须实现此方法来处理结果集中的每一行数据。此方法不应调用ResultSet上的next();它应该只提取当前行的值
接口结果文本采集器
extractData(ResultSet rs)抛出SQLException、DataAccessException
实现必须实现此方法才能处理整个结果集
如果没有return
语句,框架已经调用了next()
,因此当您调用next()
时,它将返回false并跳过代码。使用return
语句,您应该反复调用next()
,直到处理完所有行
使用2个重载的正确方法如下所示,通过对函数接口的强制转换来消除方法重载的模糊性:
String sql=“选择SUM(asts.downloads)作为下载”+
“,金额(asts.amount_)
return new Object();