百万级Excel数据导入到Oracle数据库

目的:将Excel数据导入到Oracle数据库中去(可以实现百万级数据),看了一下网上的,没有找到springboot+mybatis+Oracel实现的,只有自己写一个了。

首先要建立一个springboot项目,并连接到数据库。以前写过一个模板。springboot+Oracle模板

先来看看想要的做的模型

存入数据的表
Excel格式

直接上代码:

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>

贴一张结构图吧

结构图

就写到这吧

转发请标明出处:https://blog.csdn.net/y_yanghao/article/details/104937888
有问题可以留言
  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Excel文件中的数据导入Oracle数据库可以使用以下步骤: 1. 首先,需要将Excel文件读取到C#中,可以使用NPOI库来读取Excel文件中的数据。 2. 连接Oracle数据库,并打开连接。 3. 创建一个OracleCommand对象,该对象用于执行SQL命令。 4. 遍历Excel文件中的每一行数据,并将数据插入到Oracle数据库中,可以使用OracleCommand对象的ExecuteNonQuery方法来执行SQL语句。 以下是一个示例代码: ```csharp using System; using System.Data; using System.Data.OracleClient; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.SS.Util; // 读取Excel文件 HSSFWorkbook workbook = new HSSFWorkbook(new FileStream("Excel文件路径", FileMode.Open)); ISheet sheet = workbook.GetSheetAt(0); // 连接Oracle数据库 string connectionString = "Data Source=数据库地址;User ID=用户名;Password=密码;"; OracleConnection connection = new OracleConnection(connectionString); connection.Open(); // 创建OracleCommand对象 OracleCommand command = new OracleCommand(); command.Connection = connection; // 遍历Excel文件中的每一行数据,将数据插入到Oracle数据库中 for (int i = sheet.FirstRowNum + 1; i <= sheet.LastRowNum; i++) { IRow row = sheet.GetRow(i); if (row == null) continue; string col1 = row.GetCell(0).ToString().Trim(); string col2 = row.GetCell(1).ToString().Trim(); string col3 = row.GetCell(2).ToString().Trim(); string sql = "insert into table_name(col1, col2, col3) values(:col1, :col2, :col3)"; command.CommandText = sql; command.Parameters.Clear(); command.Parameters.Add(new OracleParameter(":col1", col1)); command.Parameters.Add(new OracleParameter(":col2", col2)); command.Parameters.Add(new OracleParameter(":col3", col3)); command.ExecuteNonQuery(); } // 关闭连接 connection.Close(); ``` 需要注意的是,在执行SQL语句时,使用了参数化查询,可以防止SQL注入攻击。另外,需要根据Excel文件和Oracle数据库的实际情况,修改代码中的表名、列名和连接字符串等信息。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值