zoukankan      html  css  js  c++  java
  • MyBatis的关于批量数据操作的测试

    摘录自:http://www.linuxidc.com/Linux/2012-05/60863.htm

    MyBatis的前身就是著名的Ibatis,不知何故脱离了Apache改名为MyBatis。
    MyBatis所说是轻量级的ORM框架,在网上看过一个测试报告,感觉相比于Hibernate来说,优势并不明显。

    下面说一下比较有趣的现象,根据MyBatis的官方文档,在获得sqlSession时,它有为批量更新而专门准备的:

    1. session = sessionFactory.openSession();//用于普通update   
    2. session = sessionFactory.openSession(ExecutorType.BATCH, true);//用于批量update  
     一般来说,对MYSQL数据库批量操作时速度取决于,是为每一个处理分别建立一个连接,还是为这一批处理一共建立一个连接。按MyBatis的手册说明,选择ExecutorType.BATCH意味着,获得的sqlSession会批量执行所有更新语句。不过我测试了一下,批量插入1000条数据,发觉ExecutorType.BATCH方式的效率居然比普通的方式差很多。我测试用的Mapper中的insert配置如下,再用for循环插入1000条记录:
    1. <insert id="insert" parameterType="sdc.mybatis.test.Student">  
    2.      <!-- WARNING - @mbggenerated This element is automatically generated by   
    3.           MyBatis Generator, do not modify. This element was generated on Mon May 09   
    4.           11:09:37 CST 2011. -->  
    5.      insert into student (id, name, sex,  
    6.      address, telephone, t_id  
    7.      )  
    8.      values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},  
    9.     #{sex,jdbcType=VARCHAR},  
    10.     #{address,jdbcType=VARCHAR}, #{telephone,jdbcType=VARCHAR}, #{tId,jdbcType=INTEGER}  
    11.     )  
    12. </insert>  

    1、 我不清楚原因在哪里, 就配置了MyBatis的log4j,想查看下日志。下载了log4j.jar和commons-logging.jar并配置到项目的类路径,然后在代码路径下新建文件log4j.properties,内容如下:

      1. log4j.rootLogger=DEBUG, stdout  
      2. # SqlMap logging configuration...  
      3. log4j.logger.com.ibatis=DEBUG  
      4. log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG  
      5. log4j.logger.com.ibatis.sqlmap.engine.cache.CacheModel=DEBUG  
      6. log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientImpl=DEBUG  
      7. log4j.logger.com.ibatis.sqlmap.engine.builder.xml.SqlMapParser=DEBUG  
      8. log4j.logger.com.ibatis.common.util.StopWatch=DEBUG  
      9. log4j.logger.java.sql.Connection=DEBUG  
      10. log4j.logger.java.sql.Statement=DEBUG  
      11. log4j.logger.java.sql.PreparedStatement=DEBUG  
      12. log4j.logger.java.sql.ResultSet=DEBUG  
      13. # Console output...  
      14. log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
      15. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
      16. log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n  

    2、然后再次测试普通的sqlSession,发现日志内容中虽然插入了1000条数据,但只新建了一次连接,最后又关闭了该连接(日志如下)。也就是说MyBatis中的普通sqlSession好像已经对批量插入默认是一次连接中完成,那么还提供ExecutorType.BATCH方式干什么,况且该方式好像效率也不行,或者是我使用ExecutorType.BATCH方式不对??

    1. DEBUG [main] - Created connection 3502256.  
    2. DEBUG [main] - ooo Connection Opened  
    3. DEBUG [main] - ==>  Executing: insert into student ( name, sex, address, telephone, t_id ) values ( ?, ?, ?, ?, ? )   
    4. DEBUG [main] - ==> Parameters: 新人0(String), male(String), addr0(String), dd(String), 3(Integer)  
    5. DEBUG [main] - ==>  Executing: insert into student ( name, sex, address, telephone, t_id ) values ( ?, ?, ?, ?, ? )   
    6. DEBUG [main] - ==> Parameters: 新人1(String), male(String),   
    7. ...............  
    8. ...............  
    9. DEBUG [main] - xxx Connection Closed  
    10. DEBUG [main] - Returned connection 3502256 to pool.  

    3、最后一点是关于数据库批量插入时sql语句级的优化,我特意测试了两种方式,在StudentMapper中配置了两种insert模式。第一种对应insert value1,insert value2,,,,;第二种对应insert values (value1, value2,....)。发现后者果然比前者快很多啊。下面是两种insert模式,及测试结果对应图: 

    1. <!-- 在外部for循环调用一千次 -->  
    2. <insert id="insert" parameterType="sdc.mybatis.test.Student">  
    3.     insert into student (id, name, sex,  
    4.     address, telephone, t_id  
    5.     )  
    6.     values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},  
    7.     #{sex,jdbcType=VARCHAR},  
    8.     #{address,jdbcType=VARCHAR}, #{telephone,jdbcType=VARCHAR}, #{tId,jdbcType=INTEGER}  
    9.     )  
    10. </insert>  
    11. <!--  批量 ,传入一个长度为1000的list  -->  
    12. <insert id="insertBatch" >  
    13.     insert into student ( <include refid="Base_Column_List" /> )   
    14.     values   
    15.     <foreach collection="list" item="item" index="index" separator=",">  
    16.         (null,#{item.name},#{item.sex},#{item.address},#{item.telephone},#{item.tId})  
    17.     </foreach>  
    18. </insert>  

     

  • 相关阅读:
    luogu P1833 樱花 看成混合背包
    luogu P1077 摆花 基础记数dp
    luogu P1095 守望者的逃离 经典dp
    Even Subset Sum Problem CodeForces
    Maximum White Subtree CodeForces
    Sleeping Schedule CodeForces
    Bombs CodeForces
    病毒侵袭持续中 HDU
    病毒侵袭 HDU
    Educational Codeforces Round 35 (Rated for Div. 2)
  • 原文地址:https://www.cnblogs.com/haimishasha/p/5709015.html
Copyright © 2011-2022 走看看