zoukankan      html  css  js  c++  java
  • 【JDBC】使用Spring提供的JDBCTemplate通过PrepareStatement向MySql数据库插入千万条数据,耗时32m47s,速度提升有限

    数据库环境还和原来一样,只是从Statement换成了PrepareStatement,都说PrepareStatement因为预编译比Statement快,但是实际运行真快不了多少。

    代码如下:

    package com.hy.action.jdbc;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.sql.Timestamp;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import org.apache.log4j.Logger;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.jdbc.core.JdbcTemplate;
    
    public class BatchJDBCPstmtInsert {
        private static Logger logger = Logger.getLogger(BatchJDBCPstmtInsert.class);
        
        public static void main(String[] args) {
            long startTime = System.currentTimeMillis();
            
            //把beans.xml的类加载到容器
            ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
            JdbcTemplate jt=(JdbcTemplate)applicationContext.getBean("jdbcTemplate");
            
            // Initialize conn&pstmt
            Connection conn=null;
            PreparedStatement pstmt = null; 
            
            try {
                conn =jt.getDataSource().getConnection();
                conn.setAutoCommit(false);
                pstmt = conn.prepareStatement("insert into emp(name,age,cdate) values (?,?,?)");
                
                String ctime="2017-11-01 00:00:01";
                long clong=getVlaueFrom(ctime);
                
                int index=0;
                
                for(int i=0;i<10000;i++) {
                    for(int j=0;j<1000;j++) {
                        index++;
                        
                        pstmt.setString(1,"'E:"+index+"'");  
                        pstmt.setInt(2, index % 100);   
                        pstmt.setTimestamp(3, new Timestamp(clong));
                        pstmt.addBatch();
                        
                        clong+=1000;
                    }
                    
                    pstmt.executeBatch(); 
                    pstmt.clearBatch();
                    conn.commit();
                    logger.info("#"+i+" 1000 records have been inserted to table:'emp'.");
                }
            } catch (SQLException e) {
                logger.error("Error happened:"+e);
                try {
                    conn.rollback();
                } catch (SQLException e1) {
                    logger.error("Can not rollback because of the error:'"+e+"'.");
                }
            }finally {
                try {
                    pstmt.close();
                    conn.close();
                    
                    long endTime = System.currentTimeMillis();
                    logger.info("Time elapsed:" + toDhmsStyle((endTime - startTime)/1000) + ".");
                } catch (SQLException e1) {
                    logger.error("Can not close connection because of the error:'"+e1+"'.");
                }
            }
        }
        
        private static long getVlaueFrom(String timeStr) {
                SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date dt;
                try {
                    dt = sdf.parse(timeStr);
                    return dt.getTime();
                } catch (ParseException e) {
                    logger.error("Can not parse '"+timeStr+"' to format'yyyy-MM-dd HH:mm:ss'.");
                    
                    return -1;
                }
        }
        
        
         // format seconds to day hour minute seconds style
        // Example 5000s will be formatted to 1h23m20s
        private static String toDhmsStyle(long allSeconds) {
            String DateTimes = null;
            
            long days = allSeconds / (60 * 60 * 24);
            long hours = (allSeconds % (60 * 60 * 24)) / (60 * 60);
            long minutes = (allSeconds % (60 * 60)) / 60;
            long seconds = allSeconds % 60;
            
            if (days > 0) {
                DateTimes = days + "d" + hours + "h" + minutes + "m" + seconds + "s";
            } else if (hours > 0) {
                DateTimes = hours + "h" + minutes + "m" + seconds + "s";
            } else if (minutes > 0) {
                DateTimes = minutes + "m" + seconds + "s";
            } else {
                DateTimes = seconds + "s";
            }
    
            return DateTimes;
        }
    }

    输出:

     INFO [main] - #9990 1000 records have been inserted to table:'emp'.
     INFO [main] - #9991 1000 records have been inserted to table:'emp'.
     INFO [main] - #9992 1000 records have been inserted to table:'emp'.
     INFO [main] - #9993 1000 records have been inserted to table:'emp'.
     INFO [main] - #9994 1000 records have been inserted to table:'emp'.
     INFO [main] - #9995 1000 records have been inserted to table:'emp'.
     INFO [main] - #9996 1000 records have been inserted to table:'emp'.
     INFO [main] - #9997 1000 records have been inserted to table:'emp'.
     INFO [main] - #9998 1000 records have been inserted to table:'emp'.
     INFO [main] - #9999 1000 records have been inserted to table:'emp'.
     INFO [main] - Time elapsed:32m47s.

    数据库的情况:

    --END-- 2019年10月13日14:35:50

  • 相关阅读:
    用C++发邮件
    python打包程序py2exe实战
    分享:Python: 数据分析资源
    Socket传输文件时进行校验(简单解决TCP粘包问题)
    第二回 基类的架造方法应该为子类想的多一些
    第一回 要想知道为什么抽象出基类,应该先对基类有一个比较明确的认识
    树型结构~无限级联下拉列表框
    为什么我要将数据库上下文进行抽象,为它生产一个基类有用吗~目录
    将不确定变为确定~真的是SqlDataReader引起的超时?
    张学友 《她来听我的演唱会》
  • 原文地址:https://www.cnblogs.com/heyang78/p/11666521.html
Copyright © 2011-2022 走看看