MyBatis批量插入和性能问题
来源:互联网 发布:滑板淘宝 编辑:程序博客网 时间:2024/05/18 19:37
MyBatis支持了批量插入的配置和语法。如下:
<insert id="insertByBatch" parameterType="java.util.List">BEGIN<foreach collection="list" item="item" separator=";">INSERT INTO T_OPT_HANDOVERBILL_DETAIL (ID, HANDOVER_NO, WAYBILL_NO, TRANSPORT_TYPE, HANDOVER_GOODS_QTY, HANDOVER_WEIGHT, ACTUAL_WEIGHT,HANDOVER_VOLUME, ACTUAL_VOLUME, NOTES, GOODS_NAME, PACKING, BE_VALUABLE, RECEIVE_ORG_NAME, REACH_ORG_NAME,RECEIVER_NAME, DEST_REGION_NAME, GOODS_QTY, WAYBILL_FEE, DECLARATION_VALUE, CURRENCY_CODE, CREATE_TIME,ORIG_ORG_CODE, HANDOVER_TYPE, COD_AMOUNT, BE_JOIN_CAR, BE_FAST_GOODS, IS_INIT, WAYBILL_NOTES,TRANSPORT_TYPE_CODE, MODIFY_TIME) VALUES (#{item.id,jdbcType=VARCHAR}, #{item.handoverNO,jdbcType=VARCHAR}, #{item.waybillNO,jdbcType=VARCHAR},#{item.transportType,jdbcType=VARCHAR}, #{item.handoverGoodsQty,jdbcType=NUMERIC}, #{item.handoverWeight,jdbcType=NUMERIC},#{item.actualWeight,jdbcType=NUMERIC}, #{item.handoverVolume,jdbcType=NUMERIC}, #{item.actualVolume,jdbcType=NUMERIC},#{item.notes,jdbcType=VARCHAR}, #{item.goodsName,jdbcType=VARCHAR}, #{item.packing,jdbcType=VARCHAR},#{item.beValuable,jdbcType=VARCHAR}, #{item.receiveOrgName,jdbcType=VARCHAR}, #{item.reachOrgName,jdbcType=VARCHAR},#{item.receiverName,jdbcType=VARCHAR}, #{item.destRegionName,jdbcType=VARCHAR}, #{item.goodsQty,jdbcType=VARCHAR},#{item.waybillFee,jdbcType=NUMERIC}, #{item.declarationValue,jdbcType=NUMERIC}, #{item.currencyCode,jdbcType=VARCHAR},#{item.createTime,jdbcType=DATE}, #{item.origOrgCode,jdbcType=VARCHAR}, #{item.handoverType,jdbcType=VARCHAR},#{item.codAmount,jdbcType=NUMERIC}, #{item.beJoinCar,jdbcType=VARCHAR}, #{item.beFastGoods,jdbcType=VARCHAR},#{item.isInit,jdbcType=VARCHAR}, #{item.waybillNotes,jdbcType=VARCHAR}, #{item.transportTypeCode,jdbcType=VARCHAR}, #{item.modifyTime,jdbcType=DATE})</foreach>;END;</insert>Java代码:
public void insertByBatch(List<HandOverBillDetailEntity> list) {long start = System.currentTimeMillis();getSqlSession().insert(NAME_SPACE + ".insertByBatch", list);long end = System.currentTimeMillis();System.out.println("批量插入耗时:" + (end - start) + "ms");}Java代码中getSqlSession是通过Spring获得。直接调用Spring的insert方法,将要插入表的对象list作为参数传递。NAME_SPACE值为mybatis配置文件中namespace的值。利用MyBatis的foreach标签,传递List对象。执行即可达到插入的效果。
此处在foreach之前和之后,用了begin和end,测试用的是Oracle,以这种方式批量插入速度回更快。
性能问题:
(1)Mybatis变量绑定不当引发的性能隐患
在value值中,我们用到了mybatis的变量绑定。用的是#{}方式,还有一种方式${}。
默认情况下,使用#{}语法,MyBatis会用PreparedStatement语句当做占位符,并且安全的设置PreparedStatement参数,可以避免SQL注入漏洞和钓鱼漏洞,这个过程中MyBatis会进行必要的安全检查和转义。
示例1:用#{}
执行SQL:Select * from emp where name = #{employeeName}
参数:employeeName=>Smith
解析后执行的SQL:Select * from emp where name = ?
示例2:用${}
执行SQL:Select * from emp where name = ${employeeName}
参数:employeeName传入值为:Smith
解析后执行的SQL:Select * from emp where name =Smith
可以看出,${}方式影响SQL语句的预编译,Oracle编译器解析时会进行硬解析,会造成很多临时游标变量的绑定,导致数据库性能下降。所以从安全性和性能的角度出发,能使用#{}的情况下就不要使用${}
(2)一次批量插入过多造成的性能隐患
虽然mybatis和oracle能支持批量插入,但也并不意味着不限插入语句的数量。经过实际的测试和性能验证,一次批量插入的数据条数很大时,oracle将不支持语句执行,可能直接报错:程序太大。而且一次插入数据量大,执行完成的耗费时间将以指数级增长。
如下为我在自身机器上做的简单测试:
- MyBatis批量插入和性能问题
- Mybatis批量插入数据问题
- Mybatis批量更新和插入
- mybatis批量更新和插入
- mybatis之批量插入和批量删除
- MyBatis中批量插入和批量更新
- 关于mybatis+mysql批量插入的问题
- mybatis批量插入,主键自增问题
- Mybatis批量更新和插入数据
- MyBatis Insert返回主键和批量插入
- mybatis批量插入和修改sql语句?
- mybatis中 mysql 和orcale批量插入
- mybatis批量插入oracle大量数据记录性能问题解决
- 提高mysql 批量插入和更新性能
- Mybatis中的foreach方法,批量插入和批量删除
- mybatis批量插入、批量删除
- Mybatis 批量插入、批量更新
- Mybatis-批量查询&&批量插入
- 各大平台免费接口
- linux下查看和添加PATH环境变量
- 总结【待续】
- Socket的accept函数解析
- 371. Sum of Two Integers
- MyBatis批量插入和性能问题
- 匈牙利算法 hdu 2063(过山车)
- 浏览器加载和渲染html的顺序
- android之Handler的使用
- centos下的mysql安装
- 平滑过渡的战争迷雾(一) 原理:Warcraft3地形拼接算法
- 2016.8.17 C组总结
- 项目上用到压力测试,记录loadrunner
- 网址资源 页面有点乱,请谅解。