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

[经验分享] MyBatis的关于批量数据操作的体会

[复制链接]

尚未签到

发表于 2016-11-27 08:32:50 | 显示全部楼层 |阅读模式

  •  MyBatis的前身就是著名的Ibatis,不知何故脱离了Apache改名为MyBatis。

     MyBatis所说是轻量级的ORM框架,在网上看过一个测试报告,感觉相比于Hibernate来说,优势并不明显。

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


session
=
sessionFactory.openSession();
//
用于普通update


session
=
sessionFactory.openSession(ExecutorType.BATCH,
true
);
//
用于批量update





 一般来说,对MYSQL数据库批量操作时速度取决于,是为每一个处理分别建立一个连接,还是为这一批处理一共建立一个连接。按MyBatis的手册说
明,选择ExecutorType.BATCH意味着,获得的sqlSession会批量执行所有更新语句。不过我测试了一下,批量插入1000条数据,
发觉ExecutorType.BATCH方式的效率居然比普通的方式差很多
。我测试用的Mapper中的insert配置如下,再用for循环插入1000条记录:

DSC0000.gif




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
>









  

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






    log4j.rootLogger=DEBUG, stdout
    # SqlMap logging configuration...
    log4j.logger.com.ibatis=DEBUG
    log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
    log4j.logger.com.ibatis.sqlmap.engine.cache.CacheModel=DEBUG
    log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientImpl=DEBUG
    log4j.logger.com.ibatis.sqlmap.engine.builder.xml.SqlMapParser=DEBUG
    log4j.logger.com.ibatis.common.util.StopWatch=DEBUG
    log4j.logger.java.sql.Connection=DEBUG
    log4j.logger.java.sql.Statement=DEBUG
    log4j.logger.java.sql.PreparedStatement=DEBUG
    log4j.logger.java.sql.ResultSet=DEBUG
    # Console output...
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n










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






    DEBUG
    [main] - Created connection
    3502256
    .


    DEBUG
    [main] - ooo Connection Opened

    DEBUG
    [main] -
    ==>
      Executing: insert into student
    (
    name
    ,
    sex
    ,
    address
    ,
    telephone
    ,
    t_id
    )
    values
    (
    ?
    ,
    ?
    ,
    ?
    ,
    ?
    ,
    ?
    )


    DEBUG
    [main] -
    ==>
    Parameters: 新人0
    (
    String
    ),
    male
    (
    String
    ),
    addr0
    (
    String
    ),
    dd
    (
    String
    ),

    3
    (
    Integer
    )


    DEBUG
    [main] -
    ==>
      Executing: insert into student
    (
    name
    ,
    sex
    ,
    address
    ,
    telephone
    ,
    t_id
    )
    values
    (
    ?
    ,
    ?
    ,
    ?
    ,
    ?
    ,
    ?
    )


    DEBUG
    [main] -
    ==>
    Parameters: 新人1
    (
    String
    ),
    male
    (
    String
    ),


    ...............


    ...............


    DEBUG
    [main] - xxx Connection Closed

    DEBUG
    [main] - Returned connection
    3502256
    to pool
    .









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






    <!--
    在外部for循环调用一千次
    -->


    <
    insert
    id
    ="insert"
    parameterType
    ="sdc.mybatis.test.Student"
    >

    insert into student (id, name, sex,
    address, telephone, t_id
    )
    values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
    #{sex,jdbcType=VARCHAR},
    #{address,jdbcType=VARCHAR}, #{telephone,jdbcType=VARCHAR}, #{tId,jdbcType=INTEGER}
    )

    </
    insert
    >


    <!--
      批量 ,传入一个长度为1000的list  
    -->


    <
    insert
    id
    ="insertBatch"

    >

    insert into student (

    <
    include
    refid
    ="Base_Column_List"

    />
    )
    values

    <
    foreach
    collection
    ="list"
    item
    ="item"
    index
    ="index"
    separator
    =","
    >

    (null,#{item.name},#{item.sex},#{item.address},#{item.telephone},#{item.tId})

    </
    foreach
    >


    </
    insert
    >









      DSC0001.png
  附录:


  • MyBatis配置文件的DTD文件(与Ibatis3不同):http://mybatis.org/dtd/
  • MyBatis的中文手册:http://mybatis.googlecode.com/files/MyBatis%203%20User%20Guide%20Simplified%20Chinese.pdf

运维网声明 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-305980-1-1.html 上篇帖子: MyBatis批量大数据测试的一些结果 下篇帖子: MyBatis的关于批量数据操作的测试
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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