JdbcTemplate带in参数的写法
好吧。几种带in参数的预编译SQL(绑定变量)方法马上补全了。
Hibernate带in参数套路
Oracle存过带in参数套路
终于遇到JdbcTemplate带in参数的绑定变量问题了,果然又是坑[捂脸]。先吐槽一下:spring的这个JdbcTemplate真不好用。
来一段代码:
String sql="update a set a.name=?,a.address=? where a.id in (?)";
List<Object> params=new ArrayList<Object>();
//有人说这里为什么不用Object数组,用list然后再toArray多此一举啊,实际上我改的这个sql是动态拼接的一堆set xx=xx,无法确定几个参数,这里为了举例写了个简单的。
params.add("张三");
params.add("火星");
//注意看这第三个参数
//由于之前踩了Hibernate的坑,也猜到参数不能写成字符串形式,比如params.add("1,2,3");所以就写成了
params.add(Arrays.asList(new String[]{"1","2","3","4"}));
getJdbcTemplate().update(sql,params.toArray());
这是个很简单的例子,根据ID集合修改字段。我本以为这样就可以了,然鹅,事实是残酷的。
java.sql.SQLException : error code [17004]; 无效的列类型
然后我又把它改成:
params.add(new String[]{“1”,”2”,”3”,”4”});
不过依然没什么卵用。
翻了下源码,第二个参数确实是Object类型可变数组,没道理不行啊。
后来查了下资料发现,有个类叫NamedParameterJdbcTemplate,看类名大概可以知道是“设置参数名的Jdbc模板”。于是,上面的代码变成了这样:
String sql="update a set a.name=:name,a.address=:address where a.id in (:id)";
Map<String,Object> params=new HashMap<String,Object>();
params.put("name","张三");
params.put("address","火星");
params.put("id",Arrays.asList(new String[]{"1","2","3","4"}));
//这里还是之前的套路,写成集合
new NamedParameterJdbcTemplate(getJdbcTemplate()).update(sql,params);
// 创建这个NamedParameterJdbcTemplate也很简单,传个JdbcTemplate进去即可。
// 注意:这个update操作传的不再是Object可变数组,是Map,因为要参数名,跟hibernate的套路一样的,参数名对应的就是key。
问题解决。
总结:如果你用JdbcTemplate的话,参数多的时候强烈推荐使用这个NamedParameterJdbcTemplate模板:
- 可以无视参数顺序,不用再像之前参数写成问号的形式一个一个顺序对应,一两个参数还好,十个八个的,眼都看瞎了。
- 这东西支持这种数组形式的参数。
其实JdbcTemplate可能也支持(但我没试),估计得用update(String sql, Object[] args, int[] argTypes)这个重载方法来update,但是参数还都是问号,不推荐。