項目中用到了批量更新。
在開發當中,可能經常會遇到批量處理這種情況,一般都再在java層面進行, 其本質是節省數據庫連接打開關閉的的次數,占用更少的運行內存。
下面先記一下批處理映射吧:
mybatis批量插入
1 <insert id="saveFeeRuleList" useGeneratedKeys="true" parameterType="java.util.List"> 2 <selectKey resultType="java.lang.String" keyProperty="id" order="AFTER"> 3 SELECT 4 LAST_INSERT_ID() 5 </selectKey> 6 INSERT INTO t_product_fee_rule( 7 <include refid="Base_Column_List"/> 8 ) 9 VALUES 10 <foreach collection="list" item="item" index="index" separator=","> 11 ( 12 #{item.id},#{item.productId}, 13 #{item.feeCode},#{item.feeValue}, 14 #{item.remarks} 15 ) 16 </foreach> 17 </insert>
mybatis批量刪除
1 <delete id="removeProductAgent" parameterType="java.util.HashMap"> 2 <foreach collection="maps.agentIds" item="item" index="index" open="" close="" separator=";"> 3 DELETE FROM t_product_agent 4 WHERE 1 = 1 5 AND product_id = #{maps.productId} 6 AND agent_id = #{item} 7 </foreach> 8 </delete>
此處的maps接口中的@Param值對應,屬於自定義變量。
void removeProductAgent(@Param("maps")Map<String, Object> map);
mybatis批量更新
1 <update id="updateByMap" parameterType="java.util.List"> 2 begin 3 <foreach collection="list" item="item" index="index" open="" 4 close="" separator=";"> 5 UPDATE PROCESS_NODE 6 SET 7 DURATION = (#{item.duration}*3600) 8 WHERE NODE_ID = #{item.nodeId} 9 AND PROCESS_TEMPLATE_ID = #{item.processTemplateId} 10 </foreach>; 11 end; 12 </update>
說說遇到到問題:
獲取mybatis的update行數,總是返回負數。后來在官網上找到原因,是由於defaultExecutorType的引起的,defaultExecutorType有三個執行器SIMPLE、REUSE和BATCH。其中BATCH可以批量更新操作緩存SQL以提高性能,但是有個缺陷就是無法獲取update、delete返回的行數。defaultExecutorType的默認執行器是SIMPLE。
名稱 | 描述 |
---|---|
SIMPLE | 執行器執行其它語句 |
REUSE | 可能重復使用prepared statements 語句 |
BATCH | 可以重復執行語句和批量更新 |
由於項目配置中啟用了BATCH執行器,UPDATE和DELETE返回的行數就丟失了,把執行器改為SIMPLE即可。
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> 3 <configuration> 4 <settings> 5 <!-- 全局映射器啟用緩存 --> 6 <setting name="cacheEnabled" value="true" /> 7 <!-- 查詢時,關閉關聯對象即時加載以提高性能 --> 8 <setting name="lazyLoadingEnabled" value="true" /> 9 <!-- 設置關聯對象加載的形態,此處為按需加載字段(加載字段由SQL指 定),不會加載關聯表的所有字段,以提高性能 --> 10 <setting name="aggressiveLazyLoading" value="false" /> 11 <!-- 對於未知的SQL查詢,允許返回不同的結果集以達到通用的效果 --> 12 <setting name="multipleResultSetsEnabled" value="true" /> 13 <!-- 允許使用列標簽代替列名 --> 14 <setting name="useColumnLabel" value="true" /> 15 <!-- 允許使用自定義的主鍵值(比如由程序生成的UUID 32位編碼作為鍵值),數據表的PK生成策略將被覆蓋 --> 16 <setting name="useGeneratedKeys" value="true" /> 17 <!-- 給予被嵌套的resultMap以字段-屬性的映射支持 --> 18 <setting name="autoMappingBehavior" value="FULL" /> 19 <!-- 對於批量更新操作緩存SQL以提高性能 --> 20 <!-- defaultExecutorType設置為BATCH有個缺陷就是無法獲取update、delete返回的行數 --> 21 <!-- <setting name="defaultExecutorType" value="BATCH" />--> 22 <!-- 數據庫超過25000秒仍未響應則超時 --> 23 <setting name="defaultStatementTimeout" value="25000" /> 24 <!-- 日志 --> 25 <!-- <setting name="logImpl" value="SLF4J"/> --> 26 </settings> 27 28 <!-- 注冊mybatis插件 --> 29 <plugins> 30 <!-- mysql分頁插件 --> 31 <plugin interceptor="com.rvho.mybatis.interceptor.MybatisPageInterceptor"> 32 <property name="databaseType" value="mysql"/> 33 </plugin> 34 </plugins> 35 </configuration>
其實這個在我的項目中是沒效果的,應該以后會有用吧,先記下來。
我的項目目前沒找到好的解決辦法,只能用try..catch來解決了,=.=|