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&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();
}
}
}