Spring Boot中使用JdbcTemplate执行带IN子句和多参数的SQL查询实现方法
实现方案
下面分别提供两种常用实现方式:
方案1:使用NamedParameterJdbcTemplate(推荐)
Spring提供的NamedParameterJdbcTemplate原生支持集合类型参数,无需手动拼接占位符,可避免SQL注入风险,是处理IN/NOT IN场景的最优选择。
Spring Boot环境已默认自动配置该类,直接注入即可使用,示例代码如下:
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.util.List; import java.util.Map; @Repository public class OrderDetailDao { @Autowired private NamedParameterJdbcTemplate namedParameterJdbcTemplate; // SQL语句直接用命名参数占位,NOT IN部分直接写:messageCodes即可 private static final String QUERY_SQL = """ SELECT * FROM order_details WHERE store_nbr = :storeNbr AND div_nbr = :divNbr AND ordered_item = :orderedItem AND message_code NOT IN (:messageCodes) AND DATE(order_date) = DATE(:orderDate) """; public List<Map<String, Object>> queryOrderDetails(Integer storeNbr, Integer divNbr, String orderedItem, List<String> messageCodes, String orderDate) { MapSqlParameterSource paramSource = new MapSqlParameterSource(); paramSource.addValue("storeNbr", storeNbr); paramSource.addValue("divNbr", divNbr); paramSource.addValue("orderedItem", orderedItem); paramSource.addValue("messageCodes", messageCodes); // 直接传入集合,框架自动生成对应数量的占位符 paramSource.addValue("orderDate", orderDate); // 如需映射为实体类,可替换为query方法配合RowMapper使用 return namedParameterJdbcTemplate.queryForList(QUERY_SQL, paramSource); } }
方案2:使用原生JdbcTemplate实现
如果必须使用原生JdbcTemplate,需要手动拼接NOT IN部分的占位符,再按顺序组装所有参数,示例代码如下:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import java.util.List; import java.util.Map; @Repository public class OrderDetailDao { @Autowired private JdbcTemplate jdbcTemplate; public List<Map<String, Object>> queryOrderDetails(Integer storeNbr, Integer divNbr, String orderedItem, List<String> messageCodes, String orderDate) { // 1. 生成NOT IN对应的占位符串,比如集合长度为3就生成?,?,? String inPlaceholders = String.join(",", messageCodes.stream().map(code -> "?").toArray(String[]::new)); // 2. 拼接完整SQL String querySql = String.format(""" SELECT * FROM order_details WHERE store_nbr = ? AND div_nbr = ? AND ordered_item = ? AND message_code NOT IN (%s) AND DATE(order_date) = DATE(?) """, inPlaceholders); // 3. 按SQL占位符顺序组装参数数组 Object[] params = new Object[3 + messageCodes.size() + 1]; params[0] = storeNbr; params[1] = divNbr; params[2] = orderedItem; int index = 3; for (String code : messageCodes) { params[index++] = code; } params[index] = orderDate; return jdbcTemplate.queryForList(querySql, params); } }
注意:如果
messageCodes集合为空,NOT IN ()会触发SQL语法错误,需要提前判断集合为空的场景,要么跳过该条件,要么做特殊逻辑处理。
内容的提问来源于stack exchange,提问作者Jolly George
相关产品推荐
相关产品推荐

