近日在公司项目中,使用到spring+mybatis的架构,特对mybatis的batch模式做了相关研究,得出以下结论:
插入多条有多种实现方式:
list方式,使用的为:insert table values(column1),(column2)的方式。
java的DAo 代码:
int insertBath(List<userShopOrderLink> recordList);
<insert id="insertBath" > insert into user_shop_order_link (seller_id, shop_id, sku1, sku1_name, three_sort1, three_sort1_name, sku2, sku2_name, three_sort2, three_sort2_name, relevance, related, binding, mark, select_link, create_date) values <foreach collection="list" item="item" index="index" separator=","> (#{item.sellerId}, #{item.shopId}, #{item.sku1}, #{item.sku1Name}, #{item.threeSort1}, #{item.threeSort1Name}, #{item.sku2}, #{item.sku2Name}, #{item.threeSort2}, #{item.threeSort2Name}, #{item.relevance}, #{item.related}, #{item.binding}, #{item.mark}, #{item.selectLink}, #{item.createDate}) </foreach> </insert>
另外一种采用bath直接由自己控制事物的提交。
Mybatis内置的ExecutorType有3种SIMPLE, REUSE, BATCH;
默认的是simple,该模式下它为每个语句的执行创建一个新的预处理语句,单条提交sql;而batch模式重复使用已经预处理的语句,批量执行所有更新语句,显然batch性能将更优;batch模式也有自己的问题,比如在Insert操作时,在事务没有提交之前,是没有办法获取到自增的id,这在某型情形下是不符合业务要求的,在同一事务中batch模式和simple模式之间无法转换,由于本项目一开始选择了simple模式,所以碰到需要批量更新时,只能在单独的事务中进行。
在代码中使用batch模式可以使用以下方式:
//从spring注入原有的sqlSessionTemplate @Autowired private SqlSessionTemplate sqlSessionTemplate; public void testInsertBatchByTrue() { //新获取一个模式为BATCH,自动提交为false的session //如果自动提交设置为true,将无法控制提交的条数,改为最后统一提交,可能导致内存溢出 SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false); //通过新的session获取mapper session.getConnection().setAutoCommit(false);//不自动提交 fooMapper = session.getMapper(FooMapper.class); int size = 10000; try { for (int i = 0; i < size; i++) { Foo foo = new Foo(); foo.setName(String.valueOf(System.currentTimeMillis())); fooMapper.insert(foo); if (i % 1000 == 0 || i == size - 1) { //手动每1000个一提交,提交后无法回滚 session.commit(); //清理缓存,防止溢出 session.clearCache(); } } } catch (Exception e) { //没有提交的数据可以回滚 session.rollback(); } finally { session.close(); } }
以上个人总结,会有不妥地方,希望给大家提供帮助。