Spring JdbcTemplate执行SQL报错但数据库直接运行正常如何解决?
问题原因
报错的根源不是SQL语法本身错误,而是JdbcTemplate的参数传递规则不符合预期:queryForObject(String sql, Class<T> requiredType, Object... args) 方法的可变入参要求为逐个传入的参数值,或Object[]类型的数组。直接将Set<Long>整体作为参数传入时,框架会把整个Set对象识别为第一个占位符的参数值,第二个占位符没有对应赋值,因此抛出No value specified for parameter 2异常。
修复方案
方案1:最小改动适配现有代码
仅需要将传入的Set转为Object数组即可:
@Override public BigDecimal vindTotalePrijsByIds(Set<Long> ids) { var sql = "select sum(prijs) from films where id in (" + "?,".repeat(ids.size()-1) + "?)"; // 把Set转换为数组传入 return template.queryForObject(sql, BigDecimal.class, ids.toArray()); }
方案2:使用NamedParameterJdbcTemplate简化IN查询
Spring提供的NamedParameterJdbcTemplate原生支持集合类型的IN参数,不需要手动拼接占位符,代码更易维护:
- 首先在Repository中注入
NamedParameterJdbcTemplate - 调整方法逻辑:
@Override public BigDecimal vindTotalePrijsByIds(Set<Long> ids) { String sql = "select coalesce(sum(prijs), 0) from films where id in (:ids)"; var paramSource = new MapSqlParameterSource("ids", ids); return namedParameterJdbcTemplate.queryForObject(sql, paramSource, BigDecimal.class); }
这里加了
coalesce函数,当查询的id都不存在时,会返回0而非null,避免后续空指针异常。
内容的提问来源于stack exchange,提问作者user15157252
相关产品推荐
相关产品推荐

