1. 程式人生 > >MyBatis 批量更新,批量更新

MyBatis 批量更新,批量更新

Mapper的內容如下:

package com.xxx.user.mapper;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.xxx.user.entity.TbSysUserPhoneBelong;

import java.util.List;

/**
 * <p>
 * 功能:
 * </p>
 *
 * @author tuzq
 * Copyright 2018 xxx.com, Inc. All rights reserved
 * @version v1.0
 * @ClassName
: xxxx * @date 2018/3/22 */
public interface TbSysUserPhoneBelongMapper extends BaseMapper<TbSysUserPhoneBelong> { /** * 歸屬地相關的批處理 * @param phoneBelongs :歸屬地list */ public void insertBatch(@Param("phoneBelongs")List<TbSysUserPhoneBelong> phoneBelongs); }

xml的內容如下:

<insert id="insertBatch" useGeneratedKeys="true" keyProperty="id" parameterType="java.util.List">
        INSERT INTO
            xxxxx
            (
                xxx,
                xxx,
                xxx,
                xxx,
                xxx,
                xxx,
                xxx,
                xxx,
                xxx,
                xxx,
                xxx,
                xxx,
                xxx,
                xxx,
                xxx
            )
        VALUES
        <foreach collection="xxxxx" item="item" index="index" separator=",">
            (
                #{item.id}
, #{item.xxx}, #{item.xxx}, #{item.types}, #{item.xxx}, #{item.xxx}, #{item.xx}, #{item.xxx}, #{item.xxx}, #{item.xxx}, #{item.xxx}, #{item.xxx}, #{item.xxx}, #{item.xxx}, #{item.xxx} ) </foreach>

Mapper.java檔案中的定義如下:

public void updateBatchById(@Param("keywordsList")List<CommunityKeywords> keywordsList);

mapper.xml中的內容如下

<update id="updateBatch" parameterType="java.util.List">
        update mydata_table
        <trim prefix="set" suffixOverrides=",">
            <trim prefix="status =case" suffix="end,">
                <foreach collection="list" item="item" index="index">
                     when id=#{item.id} then #{item.status}
                </foreach>
            </trim>
        </trim>
        where id in
        <foreach collection="list" index="index" item="item" separator="," open="(" close=")">
            #{item.id,jdbcType=BIGINT}
        </foreach>
    </update>

方法二:

<update id="updateBatchById" parameterType="java.util.List">
        <foreach collection="keywordsList" item="item" index="index" separator=";">
            UPDATE
                XXX
            <set>
                <trim suffixOverrides=",">
                    <if test="item.articleId != null">
                        article_id = #{item.articleId},
                    </if>
                    <if test="item.keywords != null">
                        keywords = #{item.keywords},
                    </if>
                    xxxxxx
                </trim>
            </set>
            WHERE
            id = #{item.id}
        </foreach>
    </update>

這種方法可能會報:

Caused by: java.sql.SQLException: sql injection violation, multi-statement not allow : update device_bd_token 
                 SET access_token=? 
                where device_id = ?
          ; 
                update device_bd_token 
                 SET access_token=? 
                where device_id = ?
    at com.alibaba.druid.wall.WallFilter.check(WallFilter.java:714)
    at com.alibaba.druid.wall.WallFilter.connection_prepareStatement(WallFilter.java:240)
    at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:448)
    at com.alibaba.druid.filter.FilterAdapter.connection_prepareStatement(FilterAdapter.java:928)
    at com.alibaba.druid.filter.FilterEventAdapter.connection_prepareStatement(FilterEventAdapter.java:122)
    at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:448)
    at com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl.prepareStatement(ConnectionProxyImpl.java:342)
    at com.alibaba.druid.pool.DruidPooledConnection.prepareStatement(DruidPooledConnection.java:318)

原因是druid給控制住了,解決辦法是:

<!-- 配置資料來源 -->
    <bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="url" value="${jdbc_url}"/>
        <property name="username" value="${jdbc_username}"/>
        <property name="password" value="${jdbc_password}"/>
        <!-- 初始化連線大小 -->
        <property name="initialSize" value="${jdbc.initialSize}"/>
        <!-- 連線池最大使用連線數量 -->
        <property name="maxActive" value="${jdbc.maxActive}"/>
        <!-- 連線池最小空閒 -->
        <property name="minIdle" value="${jdbc.minIdle}"/>
        <!-- 獲取連線最大等待時間 -->
        <property name="maxWait" value="${jdbc.maxWait}"/>
        <property name="validationQuery" value="${validationQuery}"/>
        <property name="testOnBorrow" value="false"/>
        <property name="testOnReturn" value="false"/>
        <property name="testWhileIdle" value="true"/>
        <!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}"/>
        <!-- 配置一個連線在池中最小生存的時間,單位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}"/>
        <!-- 開啟removeAbandoned功能 -->
        <property name="removeAbandoned" value="true"/>
        <!-- 1800秒,也就是30分鐘 -->
        <property name="removeAbandonedTimeout" value="${jdbc.removeAbandonedTimeout}"/>
        <!-- 關閉abanded連線時輸出錯誤日誌 -->
        <property name="logAbandoned" value="true"/>
        <!-- 監控資料庫 wall sql防火牆,注意這裡的wall-filter,預設是wall,這裡使用我們自己定義的wall-filter -->
        <property name="filters" value="mergeStat,wall-filter"/>
        <!-- 支援emoji表情 -->
        <property name="connectionInitSqls" value="set names utf8mb4;"/>
    </bean>


    <!-- 下面兩個bean是增加的過濾器,為了解決批量更新被攔截了的問題 -->
    <bean id="wall-filter" class="com.alibaba.druid.wall.WallFilter">
        <property name="config" ref="wall-config" />
    </bean>
    <bean id="wall-config" class="com.alibaba.druid.wall.WallConfig">
        <property name="multiStatementAllow" value="true"/>
    </bean>