zoukankan      html  css  js  c++  java
  • 基于Oracle的Mybatis 批量插入

    项目中会遇到这样的情况,一次性要插入多条数据到数据库中,有两种插入方法:

    方法一:

      Mybatis本身只支持逐条插入,比较笨的方法,就是遍历一个List,循环中逐条插入,比如下面这段代码 

    for(Data d : ListData) {
    dataMapper.insertSelective(d);
    }
    

        这样做的后果就是效率严重低下,因为每次循环都要向数据库提交一次,数据少的时候看不出来,但是如果上千条,花费的时间就相当多了

    方法二:

      Mybatis本身是很灵活的,因为可以自己在XML文件中编写sql进行操作,那就可以一次性将插入到数据库中,这样只用向数据库提交一次,性能也可以提高不少。下面来看一个例子:

      首先,在DataMapper.java 接口类中加入接口:

    int batchInsert(List<Data> datas);

     

      然后,在DataMapper.xml 中编写对应的实现sql,我使用的是oracle,如果是mysql或sqlserver,可能sql语句会略有区别吧:

    <insert id="batchInsert"parameterType="java.util.List"> 
     insert into DATA (ID, TEXT, STAUTS) 
     <foreach close=")"collection="list"item="item"index="index"open="("separator="union"> 
    select
    #{item.id,jdbcType=VARCHAR},
    #{item.text,jdbcType=VARCHAR},
    #{item.stauts,jdbcType=VARCHAR}
     from dual 
    </foreach>
    </insert>
    
      最后,在需要批量插入Data数据的地方调用接口:
    dataMapper.batchInsert(ListData);
    

      

    说明一下xml文件的实现,使用foreach标签,是用来拼接内部的字符串,item就相当于一个指针,用来遍历list中的对象,将每一个item的属性值复制给内部sql之后,用union拼接起来,一次性执行一个长的sql语句。   如果我们从后台打印sql执行语句的话,会看到这样的sql语句

    insert into DATA (ID, TEXT, STAUTS) 
    (
    select ?, ?, ? from dual union 
    select ?, ?, ? from dual union 
    select ?, ?, ? from dual 
    )
    

      

      相对于第一个方法,第二个方法的代码量要多出很多,但是从性能方面考虑,不管插入多少条数据,都只用向数据库提交一次,这样效率就会大幅提升。

    如果id 是使用 seq 自增长的呢?

    	<insert id="insertRoleMenu">
    		insert into ROLE_MENU_RELA (RM_ID, ROLE_ID, MENU_ID)	
    		select ROLE_MENU_RELA_SEQ.nextval,a.* from (
    		<foreach collection="list" item="rela" index="index" separator="union" open="(" close=")">
        		select  #{rela.roleId,jdbcType=DECIMAL}, #{rela.menuId,jdbcType=DECIMAL} from dual
    		</foreach>
    		) a
    	</insert>
    

      这里传入的参数为 List<ROLE_MENU_RELA> list 

    然而,如果我传入的对象role如下:

    class role
    {
    int roleId;
    List<menu> list;
    }
    

    那么要插入 role与menu 的关系表数据的方法:

    <insert id="insertRoleMenu" parameterType="com.xxx.modules.sys.entity.Role">	
    		begin	
    		<foreach collection="menuList" item="menu" index="index">
    			insert into ROLE_MENU_RELA (RM_ID, ROLE_ID, MENU_ID) values 
        		(BPMP_SYS_ROLE_MENU_RELA_SEQ.nextval, #{roleId,jdbcType=DECIMAL}, #{menu.menuId,jdbcType=DECIMAL});
    		</foreach>
    		end;
    	</insert>
    

    将所有的sql 语句放入一个块中处理

    参考链接:http://www.thinksaas.cn/topics/0/98/98721.html

  • 相关阅读:
    http://www.oschina.net/translate/elasticsearch-getting-started?cmp
    http://www.mxchip.com/talk/news/jishuwenzhang/2014-09-11/67.html
    深入理解JVM—性能监控工具
    Windows7查看本地Java安装是否成功和路径的方法
    Eclipse 编译错误 Access restriction:The type *** is not accessible due to restriction on... 解决方案
    PSYoungGen /PSOldGen/PSPermGen区别
    深入浅出Java并发包—锁机制(三)
    深入浅出Java并发包—锁机制(二)
    【转】Spring 注解学习手札(超好的springmvc注解教程)
    解决java.lang.NoClassDefFoundError: org.jdom.Content
  • 原文地址:https://www.cnblogs.com/panie2015/p/6042180.html
Copyright © 2011-2022 走看看