ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

mybatis使用批量修改語句報錯 multi-statement not allow

2021-07-14 13:58:59  阅读:205  来源: 互联网

标签:multi allow 執行 語句 item statement wallFilter true id


一、問題解決
項目里有個功能需要批量更新數據,本想直接在后台for循環里做更新操作,但想起之前看到的最好不要在循環中執行數據庫crud操作,因此就改用了直接在mybatis語句中使用foreach來執行批量更新操作(其實性能差不多,都是一條一條去更新),代碼如下:

<update id="updateListToNotDelete">
  <foreach collection="list" index="index"  item="item" open="" separator=";" close="">
    update t_sys_user_menu
     set is_delete = 0,
     object_name = #{item.objectName},
     update_date = #{item.updateDate}
     where user_menu_uid = #{item.userMenuUid}
  </foreach>
  </update>

代碼沒問題吧,但當我執行的時候就有問題了,出現了下面這個錯誤 multi-statement not allow

一臉懵逼的我還以為是執行語句寫錯了,但檢查了好多遍也沒發現問題。網上找資料,發現原來是druid配置的問題,要想執行批量更新的操作,需要添加額外的配置。
首先在數據庫連接串后加上: &allowMultiQueries=true

jdbc:mysql://192.168.1.129:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true

然后還需要在DruidConfig中添加配置(這個類需要自己新建), 主要是需要添加wallFilter配置

/**
* 使用阿里巴巴的Druid配置多數據源
* 需要在配置文件中指定,spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
* @author sxh
* @date 2019年5月5日
* @Description
*
*/
@Configuration
public class DruidConfig {   
     
     @Bean
     @ConfigurationProperties(prefix="spring.datasource")
     public DataSource druidPrimary(){
          DruidDataSource druidDataSource = new  DruidDataSource();
          List<Filter> filterList = new ArrayList<>();
          filterList.add(wallFilter());
          druidDataSource.setProxyFilters(filterList);
          return new DruidDataSource();     
     }    
     
     @Bean
    public WallFilter wallFilter(){
        WallFilter wallFilter = new WallFilter();
        wallFilter.setConfig(wallConfig());
        return wallFilter;
    }
     
     @Bean
    public WallConfig wallConfig() {
        WallConfig config = new WallConfig();
        config.setMultiStatementAllow(true);//允許一次執行多條語句
        config.setNoneBaseStatementAllow(true);//允許一次執行多條語句
        return config;
    }
}
配置完成,再次執行代碼,成功解決!

二、另一種方法
在網上查閱博客的過程中,發現執行批量更新操作還有另外一種方法,就是使用Mybatis的xml去構建sql語句,然后交給數據庫執行,這種方法不需要對數據庫進行額外的配置,直接上代碼:


```java
<update id="updateListToNotDelete">
    update t_sys_user_menu
    <trim prefix="set" suffixOverrides=",">
     is_delete = 0,
     <trim prefix="object_name =(case" suffix="end),">
          <foreach collection="list" item="item">
                   <if test="item.objectName != null">
                        when id=  #{item.id} then #{item.objectName}
                   </if>
              </foreach>
     </trim>
     <trim prefix="update_date =(case" suffix="end),">
          <foreach collection="list" item="item">
                   <if test="item.updateDate != null">
                        when id =  #{item.id} then #{item.updateDate}
                   </if>
              </foreach>
     </trim>
     </trim>
     <where>
          id in
          <foreach collection="list" item="item"  index="index" open="(" separator="," close=")">
              #{item.id}
          </foreach>
     </where>
  </update>
sql最終執行的語句:
#使用SQL一次批量更新多條記錄
UPDATE t_sys_user_menu
SET
object_name = (
CASE
WHEN user_menu_uid= 123 then 3
END
),
update_date= (
CASE
WHEN id= 1244 then '111'
END
)
WHERE id IN (123, 1244)

标签:multi,allow,執行,語句,item,statement,wallFilter,true,id
来源: https://blog.csdn.net/qq_42158122/article/details/118724113

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有