ibatis 批量update操作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ibatis 批量update操作相关的知识,希望对你有一定的参考价值。

<!-- 批量修改菜品原价和现价 -->
<update id="batchUpdateDish" parameterType="java.util.List" >
<foreach collection="list" item="item" index="index" separator=";" >
UPDATE T_DM_DISH D
<set>
<if test="item.price != null ">
D.PRICE = #item.price,jdbcType=NUMERIC,
</if>
<if test="item.discountPrice != null ">
D.DISCOUNT_PRICE = #item.discountPrice,jdbcType=NUMERIC,
</if>
</set>
WHERE D.DISH_ID = '$item.dishId'
</foreach>
</update>
--------------------------------------------------------------------------------------------
总是报错
### SQL: UPDATE T_DM_DISH D SET D.PRICE = ?, D.DISCOUNT_PRICE = ? WHERE D.DISH_ID = '3A81D31BEA0A44AB987BE4AC0B7AE23A' ; UPDATE T_DM_DISH D SET D.PRICE = ?, D.DISCOUNT_PRICE = ? WHERE D.DISH_ID = '4D80AEFE75A446DF8DE09778BB008497'
### Cause: java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符

; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符
明明是没有start 和end

上面的解析成sql就是
update Question?? set status = "OK"?? where questionId in(1,2,3,4,5...)
PS:只是单独的ibatis项目,不和spring集成??问题补充:<div class="quote_title"rensanning 写道</div<div class="quote_div"ibatis只是对JDBC的封装,真正是否能够一次性批量操作,要看你的数据库类型! /比如: / 一次插入多条数据: /INSERT INTO t (t.a, t.b, t.c) /VALUES ('key1','key2','value'), ('key1','key3','value2') ,... / /</div / / /这些明白,少量数据可以用循环来执行,如果是大量数据,在ibatis中是怎么优化的,放到同一个session中吗???问题补充:<div class="quote_title"makemyownlife 写道</div<div class="quote_div"iBatis2通过SqlMapClient提供了一组方法用于批处理实现: /startBatch() 开始批处理 /xecuteBatch() 执行批处理 / /<pre name="code" class="java"
public void create(List<Reply> replyList) try // 开始批处理
sqlMapClient.startBatch();
for (Reply reply: replyList)
// 插入操作
sqlMapClient.insert("Reply.create", reply);// 执行批处理
sqlMapClient.executeBatch();
e.printStackTrace();</pre</div / / /首先不加这两个,红色部分也可以正常执行批量插入,差别就是加了startBatch() && sqlMapClient.executeBatch(),这样的好处能说下吗?问题补充:<div class="quote_title"makemyownlife 写道</div<div class="quote_div"iBatis2通过SqlMapClient提供了一组方法用于批处理实现: /startBatch() 开始批处理 /xecuteBatch() 执行批处理 / / / public void create(List<Reply> replyList) / / try / // 开始批处理 / sqlMapClient.startBatch(); / / <span style="color: red"for (Reply reply: replyList) / // 插入操作 / sqlMapClient.insert("Reply.create", reply); / </span / // 执行批处理 / sqlMapClient.executeBatch(); / / catch (Exception e) / e.printStackTrace(); / / / / /</div / /
参考技术A 可能是单引号的问题,WHERE D.DISH_ID = '$item.dishId'

你把引号去掉试试
参考技术B 有的时候,我们需要一次性插入很多的数据或者一次性更新、删除很多的数据,这是为了提高效率。假如不用批处理 ,相当于是一条一条的插入。而批处理是一次性的修改数据,这样减少了数据库连接的消耗。
至于ibaits 执行

Java代码
sqlMapClient.startBatch();
.....
sqlMapClient.executeBatch();

,我认为ibatis是对statement的addBatch()方法做了封装。源码没看过 ,但认为原理是这样。
在我做过的项目里,基本是一次性修改万级以上的数据时 会用批处理,我会把数据分多批,一批一批的处理 这样速度快。

mybatis批量update操作的写法,及批量update报错的问题解决方法

mybatis的批量update操作写法很简单,如下:

public interface YourMapper extends BaseMapper<YourExt> {

    void updateBatch(@Param("pojos") Collection<YourExt> pojos);
}
  <update id="updateBatch" parameterType="java.util.Collection">
        <foreach collection="pojos" item = "pojo" separator= ";" >
            update your_table t set pt.your_value = #{pojo.yourValue} where pt.id = #{pojo.id}
        </foreach>
    </update>

在执行过程中报异常,但是sql和参数直接在DB里执行是好的,原因是MySql默认不支持批量更新,需要开发人员主动设置,只需要在你的数据库连接url后面加上

&allowMultiQueries=true
就好了
技术分享图片

例如我的数据库连接配置就会变成

以上是关于ibatis 批量update操作的主要内容,如果未能解决你的问题,请参考以下文章

ibatis批量插入怎么做

ibatis配置文件中update语句的写法?

ibatis

ibatis批处理和把批量数据拼成一条sql语句,哪个效能更好?

ibatis 执行sql的事务控制问题

IBatis批量插入数据