如何通过Spring JdbcTemplate生成动态的“in(...)”SQL列表?

31

是否可以通过Jdbc模板在SQL查询中生成任意的“in ()”列表:

例如:

“select * from t where c in (#)”,然而“#”可能是一个仅在运行时已知的任意值列表。


3个回答

37

如果您使用NamedParameterJdbcTemplateSimpleJdbcTemplate和命名参数,那么在Spring中是可以实现的。列表参数可以设置为java.util.List

List<String> list = new ArrayList<String>();

list.add("A");
list.add("B");
list.add("C");

List<SomeObject> result = simpleJdbcTemplate.query("SELECT * FROM t WHERE c in (:list)",
    new RowMapper<SomeObject>() { ... },
    Collections.singletonMap("list", list));

在这种情况下,Spring会根据实际列表的大小用所需数量的占位符创建SQL查询,并将命名参数替换为?

5
如果你的IN(...)参数不是字符串(文本),那么这种方法将无法使用。例如,如果你想以这种方式传递List<Long>,你会得到错误的数据类型:java.lang.NumberFormatException: For input string: "[2, 3, 4]" - Shivan Dragon
@ShivanDragon 在这种情况下有正确的方法吗?关于原始答案的一般说明。在Java 8中,您可以使用lambda格式(rs,rowNum) -> {...}代替new RowMapper <SomeObject>(){...} - gaoagong

0

SimpleJDBCTemplate现在已经过时了。您可以使用NamedParameterJdbcTemplate代替。 以下是示例代码。 如果您有多个不同类型的参数,可以使用Object作为键,否则请使用您的List<T>

String sqlAllEmpl = queryLoader.getProperty("allEmployeesByLevelAndPeriod");
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("level", levelStr);
        paramMap.put("periodList", periodList);

        gridList = namedParameterJdbcTemplate.query(sqlAllEmpl, paramMap, new YourRowMapper());

你的 sqlAllEmpl 将有两个占位符,level - 字符串和 periodList - 用于 sql 中 IN 语句的列表。


0
在Hibernate中,您可以使用以下示例:
if(tenors != null && tenors.length >0)
            sql.append(" and ip.tenor_id in (:tenors)");

.....


if(tenors != null && tenors.length >0){
    query.setParameterList("tenors", tenors);                                 
}
.....
SQLQuery query = (SQLQuery) getSession().createSQLQuery(sql.toString())

2
问题不在Hibernate方面,而是在于Spring JDBC模板。 - Igor Kupczyński

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接