JDBC执⾏批量UPDATE的⼏个坑
关于allowMultiQueries
上代码:
@Test
public void testUpdateBatch2Jdbc()throws Exception{
Connection conn = ds.getConnection();
PreparedStatement pstmt = conn.prepareStatement(
"update users set gender = 0 where id = 1;"+
"update users set gender = 0 where id = 2;"+
"update users set gender = 0 where id = 3;");
pstmt.close();
conn.close();
}
如果直接运⾏会报错:
SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to MySQL server version for the right s yntax to near 'update users set gender = 0 where id = 2;update users set gender = 0 where id = ' at line 1
解决办法:在url链接地址中添加参数allowMultiQueries=true。
关于rewriteBatchedStatements
上代码:
@Test
public void testUpdateBatchJdbc()throws Exception{
Connection conn = ds.getConnection();
PreparedStatement pstmt = conn.prepareStatement("update users set gender = ? where id = ?");
pstmt.setInt(1,0);
pstmt.setInt(2,1);
pstmt.addBatch();
pstmt.setInt(1,0);
pstmt.setInt(2,2);
pstmt.addBatch();
pstmt.setInt(1,0);
pstmt.setInt(2,3);
pstmt.addBatch();
int[] ret = uteBatch();
System.out.String(ret));
pstmt.close();
conn.close();
}
这是另⼀种执⾏批量SQL的⽅式,可以直接运⾏,但是很不幸,jdbc的驱动却不是以批量的⽅式执⾏sql的,⽽是拆分成多条来执⾏的。想要批量执⾏需要在url链接地址中添加参数rewriteBatchedStatements=true。
但是要注意:此时如果批量sql的数量⼩于2仍然是拆分执⾏的
驱动源码如下:
如果是Mybatis的批量UPDATE呢?
mybatis在执⾏批量update的时候,⼀般是这样的:
<update id="updateBatch">
<foreach collection="list"item="item"index="index"open=""close=""separator=";">
update entity
<set>
<if test="item.updaterId != null">updater_id = #{item.updaterId},</if>
<if test="item.updaterName != null">updater_name = #{item.updaterName},</if>
</set>
where id = #{item.id}
</foreach>
</update>
因此,只要设置allowMultiQueries就可以了。
Mybatis的批量INSERT是如何获取⾃动⽣成的ID?
原⽣的jdbc是怎么做到的?
上代码:
@Test
public void testInsertBatchJdbc()throws Exception{
String sql =" insert into users(name,gender)values('hello',1),('world',2),('test',1)";
Connection conn = ds.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);        uteUpdate();
ResultSet rs = GeneratedKeys();
()){
int id = rs.getInt(1);
System.out.println(id);
}
rs.close();
批量更新sql语句pstmt.close();
conn.close();
}
Mybatis是怎么做到的呢?
显然就是利⽤的GeneratedKeys:
<insert id="insertBatch"useGeneratedKeys="true"keyProperty="id">
insert into users(name, gender)
values
<foreach collection="list"item="item"separator=",">
(
#{item.name},#{der}
)
</foreach >
</insert>
结论
检查下url的链接参数,看是否添加了allowMultiQueries和rewriteBatchedStatements
Seata的分布式事务就⽤到了的uteBatch,因此⼀定要去设置rewriteBatchedStatements,否则会⼤⼤影响性能参考⽂档

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。