项目中用到了批量更新。
在开发当中,可能经常会遇到批量处理这种情况,一般都再在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来解决了,=.=|