• 关于 MyBatis MyBatis-Spring Jdbc 批量插入的各种比较分析


    因为目前SME项目中编写了一套蜘蛛爬虫程序,所以导致插入数据库的数据量剧增。就项目中使用到的3种DB插入方式进行了一个Demo分析:

    具体代码如下:

    1: MyBatis 开启Batch方式,最普通的带自动事务的插入:   

        SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH, true);
            try {
    
                Date dt1 = new Date();
    
                SemAccountMapper dao = session.getMapper(SemAccountMapper.class);
                dao.addSemAccountBatch(accounts);
                //session.commit();
                //session.clearCache();
                Date dt2 = new Date();
    
                return (dt2.getTime() - dt1.getTime()) / 1000.0;
    
            } catch (Exception e) {
                session.rollback();
                throw e;
            }   

    1.1 开启Batch,但不使用自动事务

            SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
            try {
    
                Date dt1 = new Date();
    
                SemAccountMapper dao = session.getMapper(SemAccountMapper.class);
                dao.addSemAccountBatch(accounts);
                session.commit();
                session.clearCache();
                Date dt2 = new Date();
    
                return (dt2.getTime() - dt1.getTime()) / 1000.0;
    
            }

    2: MyBatis_spring 普通的插入

            SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH, true);
            try {
                Date dt1 = new Date();
                SemAccountMapper dao = session.getMapper(SemAccountMapper.class);
                dao.addSemAccountBatch(accounts);
                session.commit();
                session.clearCache();
                Date dt2 = new Date();
                return (dt2.getTime() - dt1.getTime()) / 1000.0;
            }

    3:Jdbc 批量操作,设置普通连接字符串 

            public static final String DBURL = "jdbc:mysql://192.168.21.225:3306/sem";
    
         Connection con = null; // 表示数据库的连接对象
            Class.forName(DBDRIVER); // 1、使用CLASS 类加载驱动程序
            con = DriverManager.getConnection(DBURL, DBUSER, DBPASS); // 2、连接数据库
    
            try {
                con.setAutoCommit(false);
                String sql = "Insert into" + " sem_account(ClientId,Name,SEAccountName,SEPassword,SEStatus,Status,CreatorId,CreatedTime,LastChanged) " + " Values "
                        + " (?,?,?,?,?,?,?,?,?) ";
                PreparedStatement prest = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
    
                for (int i = 0; i < length; i++) {
                    prest.setInt(1, 1);
                    prest.setString(2, i + "");
                    prest.setString(3, i + "");
                    prest.setString(4, i + "");
                    prest.setInt(5, 1);
                    prest.setInt(6, 1);
                    prest.setInt(7, 1);
                    prest.setString(8, DateUtil.getCurrentDate());
                    prest.setString(9, DateUtil.getCurrentDate());
                    prest.addBatch();
                }
    
                Date dt1 = new Date();
    
                prest.executeBatch();
                con.commit();
    
                Date dt2 = new Date();
    
                return (dt2.getTime() - dt1.getTime()) / 1000.0;
            }

    3.1 设置批量连接字符串 rewriteBatchedStatements=true,与上面不同的只有连接字符串不同

           public static final String DBURL = "jdbc:mysql://192.168.21.225:3306/sem?rewriteBatchedStatements=true";
    

      

    以上所有方法,在测试程序中,都执行2次,防止有连接池缓存影响速度上的判断,插入数据库数据位10w条数据,得到以下分析结果:

    插入数据库方式 第一次插入10w条时间(s) 第二次插入10w条时间(s)
    MyBatis 开启Batch 自动事务提交 42.703 35.747
    MyBatis 开启Batch  关闭自动事务,自提交 38.875 40.285
    MyBatis-Spring 普通提交 37.199 36.607
    Jdbc 批量操作,普通连接字符串 98.589 97.973
    Jdbc 批量操作,设置批量操作字符串 3.311 3.244

    从以上操作来看,其中Mybatis自动事务,和Mybatis-Spring 的方法所用时间基本一致,

    而最快的操作在 Jdbc 带上批量操作参数以后的速度 3.244s。

    附带InsertBatch的Mapper文件

        <insert id="addSemAccountBatch" parameterType="SemAccount">
            Insert into sem_account
            (ClientId,Name,SyncId,SyncTime,SEId,SESyncTime,SEAccountName,SEPassword,SEApiToken,SEStatus,Cost,BudgetPerDay,Balance,Payment,ExcludeIps,RegionTargets,OpenDomains,BudgetOfflineTime,Remark,WarningRemainingDays,WarningRemainingCost,Status,CreatorId,CreatedTime,LastChanged,SearchEngineType,SearchEngineConstId)
            Values
            <foreach collection="list" item="item" index="index"
                separator=",">
                (#{item.clientId},#{item.name},#{item.syncId},#{item.syncTime},#{item.sEId},#{item.sESyncTime},#{item.sEAccountName},#{item.sEPassword},#{item.sEApiToken},#{item.sEStatus},#{item.cost},#{item.budgetPerDay},#{item.balance},#{item.payment},#{item.excludeIps},#{item.regionTargets},#{item.openDomains},#{item.budgetOfflineTime},#{item.remark},#{item.warningRemainingDays},#{item.warningRemainingCost},#{item.status},#{item.creatorId},#{item.createdTime},#{item.lastChanged},#{item.searchEngineType},#{item.searchEngineConstId})
            </foreach>
        </insert>
  • 相关阅读:
    Python列表生成
    Python 多线程
    Python面向对象编程
    map, reduce和filter(函数式编程)
    35个高级python知识点
    python之pyc
    Python之简单的用户名密码验证
    EasyUI 实例
    hibernate映射文件one-to-one元素属性
    Java中多对多映射关系
  • 原文地址:https://www.cnblogs.com/xiaolb/p/MySql-Insert-Batch.html
Copyright © 2020-2023  润新知