JDBC进⾏批量更新的两种⽅式
对于跨表批量查询,我们可以采⽤“UNION”关键字,结合⼦查询还可以进⾏分页查询,但对于批量更新,JDBC⽆法对⼦查询视图进⾏更新,如下:
update
-- ⼦查询视图
(select * from t_security_menu ) as menu
set back_url = 'URL_2'where pk = 2
-- 提⽰如下错误:
-- [Err] 1288 - The target table menu of the UPDATE is not updatable
从上⾯的错误可以看出,JDBC批量更新必须在原表上进⾏,这⼜分为两种情况:
1. 在同⼀张表上进⾏批量更新;批量更新sql语句
2. 跨表进⾏批量更新;
这⾥以Spring JDBC的NamedParameterJdbcTemplate接⼝为例,依次对两种情况进⾏说明,其他类库⽤法与此类似。
1. 同表批量更新
在同⼀张表上进⾏批量更新,如果表名相同,⽽且响应的参数个数也相同,因此执⾏的SQL必然完全相同,只是参数不⼀致,这时候可以采⽤batchUpdate⽅法,如下:
// SQL语句含有两个参数
String sql = "update t_security_menu set back_url = :b1 where pk = :p1"
// 多个参数列表
Map<String, Object> param1 = wHashMap();
param1.put("b1", "URL_1");
param1.put("p1", 1L);
Map<String, Object> param2 = wHashMap();
param2.put("b1", "URL_2");
param2.put("p1", 2L);
// 创建参数列表
Map<String, Object>[] params = new Map[]{param1, param2};
// 执⾏SQL
int[] result = this.jdbcTemplate.String(), params);
从上⾯的代码可以看出,batchUpdate是将同⼀条语句执⾏多次,只是不断更换参数内容,所以缺点也很明显,只能在同⼀张表内。2. 跨表进⾏批量更新
有时会碰到这样的情况,例如在按⽇期对表进⾏分布设计时,即每天的数据存储在⼀张单独的表内,所以需要跨表进⾏批量更新。
针对这种情况,⾸先,不能像例1⼀样,将表名作为参数,这样会出现转义错误(表名会加上单引号),所以必须单独处理每张表的SQL语句,如下:
StringBuilder builder = new StringBuilder();
// ⼀定要在语句末尾加上分号
builder.append("update t_security_menu set back_url = :b1 where pk = :p1;");
builder.append("update t_security_menu set back_url = :b2 where pk = :p2;");
// 把所有的参数放到⼀个Map对象内
Map<String, Object> param1 = wHashMap();
param1.put("b1", "URL_1");
param1.put("p1", 1L);
param1.put("b2", "URL_2");
param1.put("p2", 2L);
// ⼀定要调⽤execute⽅法
String(), param1, new PreparedStatementCallback<Object>() {
@Override
public Object doInPreparedStatement(PreparedStatement args) throws SQLException, DataAccessException {
return null;
}
});
在上⾯的例⼦中,⼀定要注意两点,⼀是每条SQL语句的末尾⼀定要加上分号,⼆是⼀定要采⽤execute⽅法(batchUpdate⽅法出错)。结论
批量插⼊、批量删除⽀持的语法都与更新类似,可以采⽤同样的解决办法,必须按表名对SQL语句进⾏整理。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论