设为首页 收藏本站
查看: 1279|回复: 0

[经验分享] Mybatis 批量插入、存储过程 本文地址

[复制链接]

尚未签到

发表于 2016-11-26 08:06:22 | 显示全部楼层 |阅读模式
Mybatis 批量插入、存储过程
  本文地址,转载注明出处:http://www.cnblogs.com/sunwufan/archive/2012/04/27/2473308.html
  本文将详细讲解Mybatis访问MySQL数据库的三种方式及测试效果。
  三种方式:simple方式(基本数据库逐条访问)、batch方式(批量操作)、procedure方式(存储过程)。
  文章主要内容:


  • 准备工作:数据库建立、存储过程建立等。
  • Eclipse中的项目搭建。
  • 所得数据分析,工作原理浅析。
  1.准备工作:
  命令行还是图形界面?这个随意,总之建完就这么个东西。

DSC0000.gif MySQL存储过程代码

  num_in为执行插入操作的次数,在java中设好,传入。
  不管什么方式,最终效果一样就可进入下一步。
     本文地址,转载注明出处:Mybatis 批量插入、存储过程
  2.Eclipse中的项目搭建。
  建立javaProject,最终目录结构。

DSC0001.gif Configuration.xml
DSC0002.gif

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     <environments default="myexample">
5         <environment id="myexample">
6             <transactionManager type="JDBC" />
7             <dataSource type="POOLED">
8                 <property name="driver" value="com.mysql.jdbc.Driver" />
9                 <property name="url" value="jdbc:mysql://localhost:3306/javaweb" />
10                 <property name="username" value="root" />
11                 <property name="password" value="admin"/>
12             </dataSource>
13         </environment>
14     </environments>
15     <mappers>
16         <mapper resource="person.xml"/>
17     </mappers>
18 </configuration>






log4j.properties


person.xml


1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 <mapper namespace="org.wufan.dao.PersonDao">
4
5
6     <insert id="insert" parameterType="org.wufan.vo.Person"
7         keyProperty="id" keyColumn="GENERATED_KEY" useGeneratedKeys="true">
8         INSERT INTO person ( name, age, sex, password)
9         VALUES (
10         #{name},#{age},#{sex},#{password} )
11     </insert>
12
13
14     <insert id="insertBatch" parameterType="org.wufan.vo.Person"
15         keyProperty="id" keyColumn="GENERATED_KEY" useGeneratedKeys="true">
16         INSERT INTO person ( name, age, sex, password)
17         VALUES
18         <foreach collection="persons" item="item" index="index"
19             separator=",">
20             (#{item.name},#{item.age},#{item.sex},#{item.password})
21         </foreach>
22     </insert>
23
24
25     <insert id="insertByProc" statementType="CALLABLE">
26         {call insertPro(#{name},#{age},#{sex},#{password},#{num})}
27     </insert>
28
29 </mapper>





  Java代码
  pojo(vo)类

Person.java

  普通方式(for循环逐条插入)的主函数

InsertSimple.java


1 package org.wufan.test;
2
3 import java.io.IOException;
4 import org.apache.ibatis.io.Resources;
5 import org.apache.ibatis.session.SqlSession;
6 import org.apache.ibatis.session.SqlSessionFactory;
7 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
8 import org.wufan.vo.Person;
9
10 public class InsertSimple {
11
12     /**
13      * @param args
14      */
15     public static void main(String[] args) {
16
17         int num = 10000;// 插入数据量
18         SqlSessionFactory factory = null;
19         try {
20             factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("Configuration.xml"));
21         } catch (IOException e) {
22             e.printStackTrace();
23         }
24         System.out.println("进入MySQL");
25         double begin = System.currentTimeMillis();
26         SqlSession sqlSession = factory.openSession();
27         Person per = new Person();
28         for (int i = 1; i <= num; i++) {
29
30             per.setName("InsertSimple" + i);
31             per.setAge(i);
32             per.setSex("男");
33             per.setPassword("密码" + i);
34
35             sqlSession.insert("org.wufan.dao.PersonDao.insert", per);
36             sqlSession.commit();
37             // sqlSession.clearCache();
38         }
39         double time = (System.currentTimeMillis() - begin) / 1000;
40         System.out.println("插入共花费时间" + time + "s");
41     }
42
43 }





  batch方式(批量操作)的主函数

InsertBatch。java


1 package org.wufan.test;
2
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.HashMap;
6 import java.util.List;
7 import java.util.Map;
8
9 import org.apache.ibatis.io.Resources;
10 import org.apache.ibatis.session.ExecutorType;
11 import org.apache.ibatis.session.SqlSession;
12 import org.apache.ibatis.session.SqlSessionFactory;
13 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
14 import org.wufan.vo.Person;
15
16 public class InsertBatch {
17
18     /**
19      * @param args
20      */
21     public static void main(String[] args) {
22
23         int num = 10000;// 插入数据量
24         SqlSessionFactory factory = null;
25         List<Person> list = new ArrayList<Person>();
26         try {
27             factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("Configuration.xml"));
28         } catch (IOException e) {
29             e.printStackTrace();
30         }
31         Person per = new Person();
32         for (int i = 1; i <= num; i++) {
33             // per.setId(null);
34             per.setName("InsertBatchName" + i);
35             per.setAge(i);
36             per.setSex("男");
37             per.setPassword("密码" + i);
38             list.add(per);
39         }
40         double begin = System.currentTimeMillis();
41         SqlSession sqlSession = factory.openSession(ExecutorType.BATCH, false);
42
43         Map<String, List<Person>> tmp = new HashMap<String, List<Person>>();
44         tmp.put("persons", list);
45
46         sqlSession.insert("org.wufan.dao.PersonDao.insertBatch", tmp);
47         sqlSession.commit();
48
49         sqlSession.close();
50         double time = (System.currentTimeMillis() - begin) / 1000;
51         System.out.println("插入共花费时间" + time + "s");
52
53     }
54 }





  procedure方式(存储过程)的主函数

InsertProcedure。java


1 package org.wufan.test;
2
3 import java.io.IOException;
4 import java.util.HashMap;
5 import java.util.Map;
6
7 import org.apache.ibatis.io.Resources;
8 import org.apache.ibatis.session.SqlSession;
9 import org.apache.ibatis.session.SqlSessionFactory;
10 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
11
12 public class InsertProcedure {
13
14     /**
15      * @param args
16      */
17     public static void main(String[] args) {
18         int num=10000;//插入数据量
19         SqlSessionFactory factory = null;
20         ;
21         try {
22             factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("Configuration.xml"));
23         } catch (IOException e) {
24             e.printStackTrace();
25         }
26         SqlSession sqlSession = factory.openSession();
27         Map map = new HashMap();
28         map.put("name", "InsertProcName");
29         map.put("age", 11);
30         map.put("sex", "男");
31         map.put("password", "1234");
32         map.put("num", num);
33         double begin = System.currentTimeMillis();
34         sqlSession.insert("org.wufan.dao.PersonDao.insertByProc", map);
35         sqlSession.commit();
36         sqlSession.close();
37         double time = (System.currentTimeMillis() - begin) / 1000;
38         System.out.println("插入共花费时间" + time + "s");
39     }
40 }





  三种方式的控制台log
  
   普通方式InsertSimple.java

batch方式(批量操作)


procedure方式(存储过程)

如果出现以上三图,恭喜,哥们你成功了!!

  3.所得数据分析。



1     1--num = 1000 ;  
2        普通处理:3.527s
3        批量处理:0.628s  
4        存储过程处理:0.144s
5      
6     2--num = 1w;  
7        普通处理:27.465s  
8        批量处理:1.528s  
9        存储过程处理:0.585s  
10      
11     3--num = 10w;  
12        普通处理: 335.18s  
13        批量处理: 11.944s
14        存储过程处理:5.146s  
15      
16     4--num = 30w;  
17        普通处理: 885.335s     
18        批量处理:34.767s
19       存储过程处理:15.875s



  小笔记本扛不住了,测试就到这里了。
  注意:在这里由于存储数据过大,批量处理时内存会吃不消。


  • 我的笔记本到达10W条数据时,会超过MySQL默认内存设置。Eclipse会报错。
  解决办法:http://www.cnblogs.com/chy710/archive/2008/03/06/1093680.html
  当插入30w条数据时会报“Java heap space” java虚拟机内存错误
  解决办法:http://developer.iyunv.com/art/200906/128572.htm
  工作原理浅析(其实上面的DEBUG截图,已经很能说明问题了):


  • 普通方式,就是一条一条往里插。
  优点:对计算机基本没什么要求,插入方式灵活。
  缺点:重复插入大量数据时,很慢。


  • 批量处理:是把插入请求放入内存,一起提交给数据库。
  优点:比普通方式快,比存储过程灵活。
  缺点:吃内存,海量数据压力略大。


  • 存储过程:只需在程序中调用存储过程,向数据库传参,。数据库根据你建好的存储过程来跑。
  优点:最快,飞起啊!!
  缺点:较为死板,换数据库工具,还要在新的数据库中建立存储过程。改需求时维护,较为麻烦。
  从数据报告可看出,普通插入理论上就是一次函数,二阶导数为零(就尼玛直线啊!);批量处理和存储过程应该都是会有一个性价比最好的值。一阶导数恒大于零,二阶导数先正后负。
  PS:


  •  Mybatis和Ibatis还是有些不同的(虽然没用过Ibatis),网上的文章比较少,官网的用户报告下不下来,靠网友经验和自己摸索做的。本人也是被赶鸭子上架头一次做,之前都怎么敲过java代码,更别说框架了,如有错误请指正!!
  • 请不要管我要源码了,这些写的比较清楚了(基本上这就算源码了==!),用源码一点成就感都没得。

  • 别问我其他操作怎么搞,我估计也不会的,如果针对此教程调试不通过可以尽管问。
  最后是查到的一些对我有帮助的资料:
  ibatis 学习笔记(一) 批量处理 存储过程 (行文方式直接抄他的,但具体技术就不一样了,他的测试结果有点怪)
     Mybatis调用存储过程  ibatis3调用存储过程  mybatis 3.0.5 --batch insert后如何获取返回的值
         MyBatis的关于批量数据操作的体会  Java:MyBatis简单入门   MyBatis简介与配置MyBatis+Spring+MySql 

        






分类: Mybatis

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-305639-1-1.html 上篇帖子: MyBatis之ResultMap简介,关联对象 下篇帖子: MyBatis之ResultMap简介,关联对象(转)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表