百万级的数据导入到数据库中要考虑效率问题。这里使用工具类ExcelUtil.read07BySax读取数据,并用多线程将数据批量导入到数据库中。
package com.zhipei.compass.data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import com.google.common.collect.Lists;
import com.zhipei.compass.common.util.db.TemplateUtils;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.sax.handler.RowHandler;
public class IportData {
private static final Logger log = LoggerFactory.getLogger(IportData.class);
public static List<Object[]> paramList = new ArrayList<>();
public static JdbcTemplate jdbcTemplate = TemplateUtils.getEpcJdbcTemplate(url, user, password);
public static String sql = "insert into testdata(year,month,province,city,brand,factory,body_en,body,amount) values(?,?,?,?,?,?,?,?,?)";
public static void main(String args[]) {
Map<Object, Object> bodyMap = new HashMap<>();
ExcelUtil.read07BySax("d:/alldata.xlsx", -1, new RowHandler() {
@Override
public void handle(int sheetIndex, int rowIndex, List<Object> rowList) {
if (sheetIndex == 0) {
bodyMap.put(rowList.get(0), rowList.get(1));
}
else {
if (rowIndex == 0) {
return;
}
for (int i = 1; i <= 12; i++) {
Object[] objects = new Object[9];
objects[0] = rowList.get(0);
objects[1] = i;// 月份
objects[2] = rowList.get(1);
objects[3] = rowList.get(2);
objects[4] = rowList.get(4);
objects[5] = rowList.get(5);
objects[6] = rowList.get(3);
if (bodyMap.get(rowList.get(3)) != null && bodyMap.get(rowList.get(3)) != "") {
objects[7] = bodyMap.get(rowList.get(3));
} else {
objects[7] = "";
}
if (rowList.get(i + 5) != null && rowList.get(i + 5) != "") {
objects[8] = rowList.get(i + 5);
} else {
objects[8] = 0;
}
paramList.add(objects);
}
log.info("处理第{}条数据..", rowIndex);
if (paramList.size() % 100 == 0) {
// 处理数据
handleData(paramList);
paramList.clear();
}
}
}
});
if (paramList.size() > 0) {
jdbcTemplate.batchUpdate(sql, paramList);
paramList.clear();
}
}
private static void handleData(List<Object[]> paramList) {
// 数据分组l
List<List<Object[]>> groupList = Lists.partition(paramList, 60);
// 计算线程数量
int threadNum = groupList.size();
// 线程池
ExecutorService pools = Executors.newFixedThreadPool(threadNum);
// 并行执行任务
for (List<Object[]> list : groupList) {
pools.execute(new Runnable() {
@Override
public void run() {
jdbcTemplate.batchUpdate(IportData.sql,list);
log.info("多线程保存数据。。");
}
});
}
pools.shutdown();
while (!pools.isTerminated()) {
}
log.info("本次300条保存完毕。");
}
}
class RDBLoadCallable implements Callable<List<Object[]>> {
private List<Object[]> list=null;
public RDBLoadCallable(List<Object[]> _list) {
list=_list;
}
@Override
public List<Object[]> call() throws Exception {
IportData.jdbcTemplate.batchUpdate(IportData.sql,list);
return null;
}
}