namedJdbcTemplate.update处理String列表无效果,Long列表却正常
问题:NamedJdbcTemplate执行DELETE语句使用String列表时失效,Long列表正常?
问题描述
尝试使用NamedJdbcTemplate.update执行DELETE语句,但操作未生效。相关代码及日志如下:
Order类定义
public class Order { private Long cuId; private String supplierType; private String customerType; private String orderType; } final List<Order> ordersStuckInNewStatus; // 已初始化
核心代码
List<String> cuIds= ordersStuckInNewStatus.stream() .map(Order::getCuId) .map(id -> String.format("'%s'", id)) // 手动添加单引号 .collect(Collectors.toList()); System.out.println(cuIds); // 输出: ['193111000000000451'] SqlParameterSource parameters = new MapSqlParameterSource("cuIds", cuIds); System.out.println(parameters); // 输出: MapSqlParameterSource {cuIds=['1931110000000000451']} int deleteCount = 0; String sql = "DELETE FROM OLCM.REJECTED_EVENT where entity_id IN (:cuIds)"; deleteCount = namedJdbcTemplate.update(sql, parameters); log.info("Delete Count:[{}]", deleteCount);
日志输出
Query:["DELETE FROM OLCM.REJECTED_EVENT where entity_id IN (?)"], Params:[('193111000000000451')] Delete Count:[0]
注意事项:
entity_id字段类型为varchar;- 若改用
List<Long> cuIds=ordersStuckInNewStatus.stream().map(Order::getCuId).collect(Collectors.toList());则操作正常。
原因分析
问题出在手动给字符串添加单引号的操作上:
- 当传入带单引号的字符串列表时,NamedJdbcTemplate会将每个元素作为完整的字符串参数传入,最终SQL执行时相当于匹配
entity_id = '''193111000000000451'''(JDBC会自动转义参数里的单引号),但数据库中entity_id的实际值是不带单引号的193111000000000451,自然匹配不到任何记录。 - 使用Long列表时,JDBC会将参数以数值类型传入,数据库会自动将varchar类型的
entity_id隐式转换为数值类型进行匹配,因此能正确找到对应记录并删除。
解决方案
去掉手动添加单引号的步骤,直接将Long类型的cuId转换为String即可,让NamedJdbcTemplate自动处理参数绑定:
List<String> cuIds= ordersStuckInNewStatus.stream() .map(Order::getCuId) .map(String::valueOf) // 直接转String,不添加单引号 .collect(Collectors.toList());
这样参数会被正确绑定为字符串类型,与数据库中varchar类型的entity_id完全匹配,DELETE操作就能正常生效。
内容的提问来源于stack exchange,提问作者Abhishek
相关产品推荐
相关产品推荐

