Java操作csv导入,导出及存储到MySQL数据库

Java操作csv导入,导出及存储到MySQL数据库

一共要导入1209943条数据,在插入372556条数据时报错,报错内容: abandon connection, owner thread: http-8080-12, connected time nano: 2563400 查找资料,是由于数据库连接池的租用时间太短,连接被还回去导致。 解决方案:在配置数据源的文件中设置连接池中的连接租用及回收时间
<!-- 超时时间;单位为秒。180秒=3分钟 -->  
        <property name="removeAbandonedTimeout" value="28800" />  

数据源完整配置:

    <bean id="dataSourceSMG" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="driverClassName" value="${JDBC_DRIVER}" />
        <property name="url" value="${JDBC_URLSMG}" />
        <property name="username" value="${JDBC_USER}" />
        <property name="password" value="${JDBC_PWD}" />
        <property name="initialSize" value="50" />
        <property name="maxActive" value="200" />
        <property name="minIdle" value="25" />
        <property name="maxWait" value="150000" />
        <!-- 指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个.  
            这个参数设为true时,还有一个参数的设置:validationQuery:SQL查询,用来验证从连接池取出的连接,
            在将连接返回给调用者之前.如果指定,则查询必须是一个SQL SELECT并且必须返回至少一行记录
        --><property name="filters" value="stat,log4j,wall" />
        <property name="testOnBorrow" value="true" />
        <property name="validationQuery"> 
            <value>SELECT 1 FROM DUAL</value> 
        </property> 
        <!-- 连接池启动PoolPreparedStatements ,DBCP连接池可以缓存PreparedStatement,本质上就是缓存游标-->
        <property name="poolPreparedStatements" value="true" />
        <!-- 最终这个连接的游标超过Oracle的open_cursor数值(默认300),就会报错。
            所以启用了PoolPreparedStatements,一定注意设置MaxOpenPreparedStatements小于Oracle Open_Cursor的数值。 -->
        <property name="maxOpenPreparedStatements" value="25" />

        <property name="timeBetweenEvictionRunsMillis" value="3000" />
        <property name="minEvictableIdleTimeMillis" value="300000" />

        <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />  

        <!-- 超时切断连接,检查连接泄露 -->
        <!-- 超过时间限制是否回收 -->  
        <property name="removeAbandoned" value="true" />  
        <!-- 超时时间;单位为秒。180秒=3分钟 -->  
        <property name="removeAbandonedTimeout" value="28800" />  
        <!-- 关闭abanded连接时输出错误日志 -->  
        <property name="logAbandoned" value="true" /> 

    </bean>

由于数据量过大,又通过jdbc的批量处理的addBatch()来减少执行时间:
addBatch()方法是把若干sql语句装载到一起,然后通过executeBatch()方法一次送到数据库执行,执行只需要很短的时间。具体代码如下:

/**
     * csv导入hfvast_smg_1表1
     */
    @Override
    public boolean insertSMG1(Map<String, Object> map) {
        boolean flag = false;
        Connection conn = null;
        PreparedStatement ptmt = null;
        List<String> nums = (List<String>) map.get("nums");
        List<String> contents = (List<String>) map.get("contents");
        String sql = "";
        sql = "INSERT INTO `hfvast_smg_1_copy`(id,serverNum,tagNum,content,createdDate,msgFormat,type) VALUES(?,?,?,?,?,?,?);";
        int index = 1;
        int i = 0;
        try {
            conn = getOpenedConnection();
            ptmt = conn.prepareStatement(sql);
            int size = nums.size();

            if (nums.size() > 0) {

                //获取分批次数
                int ssize = (int) Math.ceil(nums.size()/30000.0);
                for (int k = 0; k < ssize; k++) {
                    if (k == ssize-1) {
                        for (int j = 0 + 30000*k; j < size; j++) {

                            String num = nums.get(j);
                            String content = contents.get(j);
                            ptmt.setString(1, num);
                            ptmt.setString(2, "10010");
                            ptmt.setString(3, num);
                            ptmt.setString(4, content);
                            ptmt.setTimestamp(5, RealUtil.createTime());
                            ptmt.setString(6, "15");
                            ptmt.setInt(7, 0);
                            ptmt.addBatch();
                        }
                    }else {
                        for (int j = 0 + 30000*k; j < 30000 * (k+1); j++) {

                            String num = nums.get(j);
                            String content = contents.get(j);
                            ptmt.setString(1, num);
                            ptmt.setString(2, "10010");
                            ptmt.setString(3, num);
                            ptmt.setString(4, content);
                            ptmt.setTimestamp(5, RealUtil.createTime());
                            ptmt.setString(6, "15");
                            ptmt.setInt(7, 0);
//                          i = ptmt.executeUpdate();
                            ptmt.addBatch();
                        }
                    }

                    int[] batch = ptmt.executeBatch();
                    for (int j : batch) {
                        if (j>0) {
                            flag = true;
                        }
                    }
                }

            }

//          for (int j = 0; j < nums.size(); j++) {
//              
//              String num = nums.get(j);
//              String content = contents.get(j);
//              ptmt.setString(1, num);
//              ptmt.setString(2, "10010");
//              ptmt.setString(3, num);
//              ptmt.setString(4, content);
//              // ptmt.setString(4, new String(content.getBytes(), "utf-8"));
//              // ptmt.setString(4, new String(content.getBytes("UTF-8"), "gbk"));
//              ptmt.setTimestamp(5, RealUtil.createTime());
//              ptmt.setString(6, "15");
//              ptmt.setInt(7, 0);
////                i = ptmt.executeUpdate();
//              ptmt.addBatch();
//          }
//          int[] executeBatch = ptmt.executeBatch();

        } catch (SQLException e) {
            e.printStackTrace();
            log.error("添加短信发送表1异常" + e.getMessage(), e);
        } finally {
            JdbcManager.closeQuietly(ptmt);
            closeConnection(conn);
        }
        return flag;
    }
一个需求要使用到csv,要支持批量插入数据库,自学以后,写出简单的demo测试类,并测试了6000条数据。
package com.surekam.smg;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;

public class CSV_Test {
    public static void main(String[] args) {

        ArrayList<String> list = new ArrayList<String>();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            list.add("1");
            list.add("12");
            list.add("123");
            list.add("1234");
            list.add("12345");
            list.add("123456");
        }

//       writeCSV(list,"D:\\dev\\telNum.csv");
        List list2 = readCSV();
        long endRead = System.currentTimeMillis();
        System.out.println("total1 = endRead - start:"+(endRead - start));//163ms

        insertTel_test(list2);

        long end = System.currentTimeMillis();
        System.out.println("total = end - start:"+(end - start));//13734ms
    }

    /**
     * 把数据导出到csv
     * @param dataList
     * @param finalPath
     */
    static void writeCSV(List dataList, String finalPath) {
        FileOutputStream out = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            File finalCSVFile = new File(finalPath);
            out = new FileOutputStream(finalCSVFile);
            osw = new OutputStreamWriter(out, "UTF-8");
            // 手动加上BOM标识
            // osw.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF }));
            bw = new BufferedWriter(osw);
            /**
             * 往CSV中写新数据
             */
            if (dataList != null && !dataList.isEmpty()) {
                // for循环遍历
                for (int i = 0; i < dataList.size(); i++) {
                    Integer num = (Integer) dataList.get(i);
                    System.out.println(num);
                    bw.append(num + "\r");
                    // bw.append(num + ",");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            if (bw != null) {
                try {
                    bw.close();
                    bw = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (osw != null) {
                try {
                    osw.close();
                    osw = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                    out = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
        System.out.println(finalPath + "数据导出成功");
    }

    /**
     * 把数据从csv中读取到list
     * @return
     */
    public static List readCSV() {
        try {
            ArrayList<String> list = new ArrayList<String>();
            BufferedReader reader = new BufferedReader(new FileReader("D:\\dev\\telNum.csv"));// 文件名
            // reader.readLine();//第一行信息,为标题信息,不用,如果需要,注释掉
            String line = null;
            while ((line = reader.readLine()) != null) {
                String item[] = line.split(",");// CSV格式文件为逗号分隔符文件,这里根据逗号切分
                String last = item[item.length - 1];// 获取到的数据
                // int value = Integer.parseInt(last);//如果是数值,可以转化为数值

                list.add(last);
                // System.out.println(last);
            }
            System.out.println("从CSV中读取到的数据:" + list);
            return list;
        } catch (Exception e) {
        }
        return null;

    }

    /**
     * 批量插入到数据库
     * @param list
     */
    public static void insertTel_test(List<String> list) {
        // 声明Connection对象
        Connection conn;
        String sql = "insert into tel_test(tel)value(?)";
        // 驱动程序名
        String driver = "com.mysql.jdbc.Driver";
        // URL指向要访问的数据库名mydata
        String url = "jdbc:mysql://132.79.253.132:3306/ats_test2?useUnicode=true&amp;characterEncoding=gbk";
        // MySQL配置时的用户名
        String user = "zzzd";
        // MySQL配置时的密码
        String password = "zzzd@lxhf_123";
        // 遍历查询结果集

        // 加载驱动程序
        try {
            Class.forName(driver);
            // 连接MySQL数据库!!
            conn = DriverManager.getConnection(url, user, password);
            PreparedStatement prep = conn.prepareStatement(sql);
            for (String value : list) {
                prep.setString(1, value);
                prep.executeUpdate();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_32332777/article/details/80696464