目的:将Excel数据导入到Oracle数据库中去(可以实现百万级数据),看了一下网上的,没有找到springboot+mybatis+Oracel实现的,只有自己写一个了。
首先要建立一个springboot项目,并连接到数据库。以前写过一个模板。springboot+Oracle模板
先来看看想要的做的模型
直接上代码:
domain下的:peopel类
public class People {
/**
* 这里定义你的Excel表头的名称,因为数据库都是字母,最好将Excel表头都改为字母
* 我这个Excel就只有四列,根据自己需求的写
*/
private String sfzh;
private String xm;
private String ssz;
private String type;
/**
* 提供getter,setter,以及toString
*
*/
}
mapper:InsertExcelToOracleMapper
@Repository
public interface InsertExcelToOracleMapper {
/**
* 这是做的一个测试(可以不看),看看自定义一个能否插入成功
* @param people
* @return
*/
int insertExcelToOracle(People people);
/**
*
* @param people集合
* @return
*/
int insertExcelToOracleList(List<People> people);
}
service层: InsertExcelToOracleService
public interface InsertExcelToOracleService {
/**其实和mapper一样,习惯了写service层就写了**/
int insertExcelToOracle(People people);
int insertExcelToOracleList(List<People> people);
}
serviceImpl实现层:InsertExcelToOracleServiceImpl
@Service
public class InsertExcelToOracleServiceImpl implements InsertExcelToOracleService {
@Autowired
private InsertExcelToOracleMapper insertExcelToOracleMapper;
@Override
public int insertExcelToOracle(People people) {
return insertExcelToOracleMapper.insertExcelToOracle(people);
}
@Override
public int insertExcelToOracleList(List<People> people) {
return insertExcelToOracleMapper.insertExcelToOracleList(people);
}
}
mapper.xml (需要自定义字段,sql语句字段要自己根据自己的要求改)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.insertexcel.mapper.InsertExcelToOracleMapper">
<resultMap id="BaseResultMap" type="com.insertexcel.domain.People">
<!--这个需要自己定义了,你的字段有可能不止这四个-->
<result column="SFZH" property="sfzh" jdbcType="VARCHAR"/>
<result column="XM" property="xm" jdbcType="VARCHAR" />
<result column="SSZ" property="ssz" jdbcType="VARCHAR"/>
<result column="TYPE" property="type" jdbcType="VARCHAR"/>
</resultMap>
<!--插入一条数据-->
<insert id="insertExcelToOracle" parameterType="com.insertexcel.domain.People">
INSERT INTO a_sfzh t (t.sfzh,t.xm,t.ssz,t.type)
VALUES (#{sfzh},#{xm},#{ssz},#{type})
</insert>
<!--插入一个集合-->
<insert id="insertExcelToOracleList" parameterType="java.util.List" useGeneratedKeys="false">
begin
<foreach collection="list" item="item" index="index" separator=";">
insert into a_sfzh
(sfzh,xm,ssz,type)
values
(
#{item.sfzh},
#{item.xm},
#{item.ssz},
#{item.type}
)
</foreach>
;end;
</insert>
</mapper>
controller层:全贴上
package com.insertexcel.controller;
import com.insertexcel.domain.People;
import com.insertexcel.service.InsertExcelToOracleService;
import com.insertexcel.util.GetListUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RequestMapping("Excel")
@RestController
public class InsertExcel {
/**
* 自定义每次插入的条数,如果插入的数据非常多的话
* 比如插入百万条数据,那么分组插入可以节省很多时间
* 并且可以防止插入时间过长二报错
* 其实最方便的还是用多线程来插入(有时间再写)
*/
private static final int OPENID_PHONE_NUM = 800;
@Autowired
private InsertExcelToOracleService insertExcelToOracleService;
/**
* 测试数据能否插入
* @return
*/
@RequestMapping("test")
public String insertOne(){
People people=new People();
people.setXm("123");
people.setSfzh("sdaf");
people.setSsz("");
people.setType("");
int a=insertExcelToOracleService.insertExcelToOracle(people);
System.out.println(a);
return "a";
}
/**
* 获取到people集合
* @return
*/
@RequestMapping("insert")
public int insertAll(){
//现获取people集合,自定义的一个从Excel获取集合的方法。
List<People> people= GetListUtil.getAllListUtil();
int listSize=people.size();
int toIndex=OPENID_PHONE_NUM;
int a;
for(int i = 0;i<people.size();i+=OPENID_PHONE_NUM){
if(i+OPENID_PHONE_NUM>listSize){//作用为toIndex最后没有800条数据则剩余几条newList中就装几条
toIndex=listSize-i;
}
List<People> newPMeSendToPhoneInfo = people.subList(i,i+toIndex);
//批量插入
a= insertExcelToOracleService.insertExcelToOracleList(newPMeSendToPhoneInfo);
}
return -1;
}
}
到这就剩从Excel读取数据获取一个集合了,直接贴代码了,需要修改的三个地方自己修改一下
package com.insertexcel.util;
/**
* 这里需要用到到的包,就怕你们导包不知道导哪个
*/
import com.insertexcel.domain.People;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class GetListUtil {
public static void main(String[] args) {
System.out.println(GetListUtil.getAllListUtil().size());
}
public static List<People> getAllListUtil() {
Workbook wb =null;
Sheet sheet = null;
Row row = null;
List<People> people=new ArrayList<>();
List<Map<String,String>> list = null;
String cellData = null;
//需要修改的地方1.filePath:你需要导入的文件,xls与xlsx文件都可以
String filePath = "E:\\test\\test.xlsx";
//需要修改的地方2.columns[]:这里是你的Excel表头,一定要写对啊,最好是字母
String columns[] = {"sfzh","xm","ssz","type"};
wb = readExcel(filePath);
if(wb != null){
//用来存放表中数据
list = new ArrayList<Map<String,String>>();
//获取第一个sheet
sheet = wb.getSheetAt(0);
//获取最大行数
int rownum = sheet.getPhysicalNumberOfRows();
//获取第一行
row = sheet.getRow(0);
//获取最大列数
int colnum = row.getPhysicalNumberOfCells();
for (int i = 1; i<rownum; i++) {
Map<String,String> map = new LinkedHashMap<String,String>();
row = sheet.getRow(i);
if(row !=null){
for (int j=0;j<colnum;j++){
cellData = (String) getCellFormatValue(row.getCell(j));
map.put(columns[j], cellData);
}
}else{
break;
}
list.add(map);
}
}
// 现在获取到所有的数据集合了
//需要修改的地方3. 现在获取到的map集合,将其存入list中去
for (Map<String,String> map : list) {
People people1=new People();
people1.setSfzh( map.get("sfzh"));
people1.setXm(map.get("xm"));
//我的数据中这两行为空,一定要注意这里,如果出现了一个null
// (也就是说你的Excel数据突然有某个单元格是没有数据的)
// 就会报错,最好还是写一个if语句判断一下每个值,如果为null,就像我下面一样直接赋值为""
people1.setType("");
people1.setSsz("");
people.add(people1);
}
return people;
}
/**
* 读取Excel数据
* @param filePath
* @return
*/
public static Workbook readExcel(String filePath){
Workbook wb = null;
if(filePath==null){
return null;
}
String extString = filePath.substring(filePath.lastIndexOf("."));
InputStream is = null;
try {
is = new FileInputStream(filePath);
if(".xls".equals(extString)){
return wb = new HSSFWorkbook(is);
}else if(".xlsx".equals(extString)){
return wb = new XSSFWorkbook(is);
}else{
return wb = null;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return wb;
}
/**
* 这里是判断数据的类型,数字还是日期,做一下转换
* @param cell
* @return
*/
public static Object getCellFormatValue(Cell cell){
Object cellValue = null;
if(cell!=null){
//判断cell类型
switch(cell.getCellType()){
case Cell.CELL_TYPE_NUMERIC:{
cellValue = String.valueOf(cell.getNumericCellValue());
break;
}
case Cell.CELL_TYPE_FORMULA:{
//判断cell是否为日期格式
if(DateUtil.isCellDateFormatted(cell)){
//转换为日期格式YYYY-mm-dd
cellValue = cell.getDateCellValue();
}else{
//数字
cellValue = String.valueOf(cell.getNumericCellValue());
}
break;
}
case Cell.CELL_TYPE_STRING:{
cellValue = cell.getRichStringCellValue().getString();
break;
}
default:
cellValue = "";
}
}else{
cellValue = "";
}
return cellValue;
}
}
最后pom.xml文件 其他的依赖就不贴了
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>