今天遇到一个问题,在mybatis 里面执行批量更新操作的问题。
mybatis本身没有提供对于批量操作的接口。所以对于批量的操作都需要自己写。
正常情况下,批量的插入,都是执行一条Sql 比如:
<insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="true">
<selectKey keyProperty="id" order="AFTER" resultType="long">
SELECT
LAST_INSERT_ID()
</selectKey>
insert into lable_tag_log (author, operate_sence,
comment, update_time, create_time
)
values
<foreach collection="list" index="index" item="item" separator=",">
(#{item.author,jdbcType=VARCHAR}, #{item.operateSence,jdbcType=VARCHAR},
#{item.comment,jdbcType=VARCHAR}, #{item.updateTime,jdbcType=TIMESTAMP}, #{item.createTime,jdbcType=TIMESTAMP}
)
</foreach>
</insert>
mybatis会将代码翻译成:insert into lable_tag_log (author, operate_sence, comment, update_time, create_time ) values (?, ?, ?, ?, ? ) , (?, ?, ?, ?, ? )
底层执行的是一条sql代码。
但是在执行批量更新的时候,由于更新的方式不同,结构也有有所不同;
<update id="batchUpdate" parameterType="java.util.List">
<foreach collection="list" item="item" index="index" open="" close="" separator=";">
update lable_type
<set>
<if test="item.lableTypeName != null">
lable_type_name = #{item.lableTypeName,jdbcType=VARCHAR},
</if>
<if test="item.ifCanRepeat != null">
if_can_repeat = #{item.ifCanRepeat,jdbcType=INTEGER},
</if>
<if test="item.author != null">
author = #{item.author,jdbcType=VARCHAR},
</if>
<if test="item.status != null">
status = #{item.status,jdbcType=INTEGER},
</if>
<if test="item.comment != null">
comment = #{item.comment,jdbcType=VARCHAR},
</if>
<if test="item.updateTime != null">
update_time = #{item.updateTime,jdbcType=TIMESTAMP},
</if>
<if test="item.createTime != null">
create_time = #{item.createTime,jdbcType=TIMESTAMP},
</if>
</set>
where id = #{item.id,jdbcType=INTEGER}
</foreach>
</update>
批量更新的时候,一次执行的过程中会执行多条sql代码,每条update之间用“;”分割,如下:
update lable_type SET lable_type_name = ?, author = ?, comment = ?, update_time = ? where id = ? ;
update lable_type SET lable_type_name = ?, author = ?, status = ?, comment = ?, update_time = ? where id = ?
在执行的时候,由于执行了多条sql代码,在mysql的一次连接的时候,默认的预处理的statement执行一条sql,如果发现有多条执行的sql就会抛异常(个人理解)
org.springframework.jdbc.BadSqlGrammarException:
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manu
al that corresponds to your MySQL server version for the right syntax to use near 'update lable_info...........'
这里面的解决办法就是:在MySQL的连接字符串URL连接中设置allowMultiQueries参数置为true。(只有MySQL Connector/J 3.1.1以上版本才支持)
url=jdbc:mysql://rds2mazmjavuruy.mysql.rds.aliyuncs.com/test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
但是值得注意的是 allowMultiQueries 是一个mysql对外提供的连接api里的一个参数
在Spring的xml文件中 需要将 “&”符号修改成“&”
到此spring mybatis的批量更新操作完成。
mybatis本身没有提供对于批量操作的接口。所以对于批量的操作都需要自己写。
正常情况下,批量的插入,都是执行一条Sql 比如:
<insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="true">
<selectKey keyProperty="id" order="AFTER" resultType="long">
SELECT
LAST_INSERT_ID()
</selectKey>
insert into lable_tag_log (author, operate_sence,
comment, update_time, create_time
)
values
<foreach collection="list" index="index" item="item" separator=",">
(#{item.author,jdbcType=VARCHAR}, #{item.operateSence,jdbcType=VARCHAR},
#{item.comment,jdbcType=VARCHAR}, #{item.updateTime,jdbcType=TIMESTAMP}, #{item.createTime,jdbcType=TIMESTAMP}
)
</foreach>
</insert>
mybatis会将代码翻译成:insert into lable_tag_log (author, operate_sence, comment, update_time, create_time ) values (?, ?, ?, ?, ? ) , (?, ?, ?, ?, ? )
底层执行的是一条sql代码。
但是在执行批量更新的时候,由于更新的方式不同,结构也有有所不同;
<update id="batchUpdate" parameterType="java.util.List">
<foreach collection="list" item="item" index="index" open="" close="" separator=";">
update lable_type
<set>
<if test="item.lableTypeName != null">
lable_type_name = #{item.lableTypeName,jdbcType=VARCHAR},
</if>
<if test="item.ifCanRepeat != null">
if_can_repeat = #{item.ifCanRepeat,jdbcType=INTEGER},
</if>
<if test="item.author != null">
author = #{item.author,jdbcType=VARCHAR},
</if>
<if test="item.status != null">
status = #{item.status,jdbcType=INTEGER},
</if>
<if test="item.comment != null">
comment = #{item.comment,jdbcType=VARCHAR},
</if>
<if test="item.updateTime != null">
update_time = #{item.updateTime,jdbcType=TIMESTAMP},
</if>
<if test="item.createTime != null">
create_time = #{item.createTime,jdbcType=TIMESTAMP},
</if>
</set>
where id = #{item.id,jdbcType=INTEGER}
</foreach>
</update>
批量更新的时候,一次执行的过程中会执行多条sql代码,每条update之间用“;”分割,如下:
update lable_type SET lable_type_name = ?, author = ?, comment = ?, update_time = ? where id = ? ;
update lable_type SET lable_type_name = ?, author = ?, status = ?, comment = ?, update_time = ? where id = ?
在执行的时候,由于执行了多条sql代码,在mysql的一次连接的时候,默认的预处理的statement执行一条sql,如果发现有多条执行的sql就会抛异常(个人理解)
org.springframework.jdbc.BadSqlGrammarException:
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manu
al that corresponds to your MySQL server version for the right syntax to use near 'update lable_info...........'
这里面的解决办法就是:在MySQL的连接字符串URL连接中设置allowMultiQueries参数置为true。(只有MySQL Connector/J 3.1.1以上版本才支持)
url=jdbc:mysql://rds2mazmjavuruy.mysql.rds.aliyuncs.com/test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
但是值得注意的是 allowMultiQueries 是一个mysql对外提供的连接api里的一个参数
在Spring的xml文件中 需要将 “&”符号修改成“&”
到此spring mybatis的批量更新操作完成。