杰瑞科技汇

Java Excel导入Oracle如何高效实现数据映射?

  • Apache POI: 用于读取 Excel 文件(.xls.xlsx)。
  • Oracle JDBC Driver: 用于连接 Oracle 数据库并执行 SQL 语句。

整体流程概览

整个过程可以分为以下几个核心步骤:

Java Excel导入Oracle如何高效实现数据映射?-图1
(图片来源网络,侵删)
  1. 环境准备: 安装必要的软件(JDK, Oracle, Excel)并添加项目依赖。
  2. 建立数据库连接: 编写 Java 代码连接到 Oracle 数据库。
  3. 读取 Excel 文件: 使用 Apache POI 读取 Excel 中的数据。
  4. 数据导入与处理: 遍历 Excel 数据,并将其插入到 Oracle 数据库中,这是最关键的一步,需要考虑性能、事务和错误处理。
  5. 资源释放: 关闭所有打开的资源(文件流、数据库连接等)。

第一步:环境准备

安装软件

  • JDK: 确保 Java Development Kit (JDK 8 或更高版本) 已安装并配置好环境变量。
  • Oracle 数据库: 确保你有一个可用的 Oracle 数据库实例,并知道 hostname, port, service_name/sid, usernamepassword
  • IDE: 如 IntelliJ IDEA 或 Eclipse。
  • Excel 文件: 准备一个用于测试的 Excel 文件。

创建 Oracle 表

假设我们要导入一个包含员工信息的 Excel 文件,内容如下:

ID NAME AGE DEPARTMENT HIRE_DATE
1001 张三 28 技术部 2025-01-15
1002 李四 35 市场部 2025-05-20
1003 王五 31 财务部 2025-11-01

在 Oracle 中创建对应的表:

CREATE TABLE employees (
    id          NUMBER(10) PRIMARY KEY,
    name        VARCHAR2(100) NOT NULL,
    age         NUMBER(3),
    department  VARCHAR2(100),
    hire_date   DATE
);

添加项目依赖

如果你使用 Maven,在 pom.xml 文件中添加以下依赖:

<dependencies>
    <!-- Apache POI for Excel (both .xls and .xlsx) -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.3</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.3</version>
    </dependency>
    <!-- Oracle JDBC Driver -->
    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc8</artifactId>
        <version>19.3.0.0</version>
    </dependency>
</dependencies>

如果你使用 Gradle,在 build.gradle 文件中添加:

Java Excel导入Oracle如何高效实现数据映射?-图2
(图片来源网络,侵删)
dependencies {
    // Apache POI for Excel
    implementation 'org.apache.poi:poi:5.2.3'
    implementation 'org.apache.poi:poi-ooxml:5.2.3'
    // Oracle JDBC Driver
    implementation 'com.oracle.database.jdbc:ojdbc8:19.3.0.0'
}

注意: ojdbc8 适用于 JDK 8,如果你使用 JDK 11 或更高版本,请使用 ojdbc11


第二步:核心代码实现

下面是一个完整的 Java 类,实现了从 Excel 导入数据到 Oracle 的功能。

我们将重点介绍两种插入方式:

  1. 逐条插入: 简单直接,但性能较差。
  2. 批量插入: 强烈推荐,性能极高。

逐条插入 (Simple Approach)

这种方式代码简单,但每次插入都会与数据库进行一次网络交互,对于大量数据来说非常慢。

Java Excel导入Oracle如何高效实现数据映射?-图3
(图片来源网络,侵删)
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExcelToOracleSimple {
    private static final String DB_URL = "jdbc:oracle:thin:@your_hostname:your_port:your_service_name";
    private static final String DB_USER = "your_username";
    private static final String DB_PASSWORD = "your_password";
    public static void main(String[] args) {
        String excelFilePath = "path/to/your/employees.xlsx";
        // 1. 读取Excel文件
        try (FileInputStream fis = new FileInputStream(excelFilePath);
             Workbook workbook = new XSSFWorkbook(fis)) {
            Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            // 2. 建立数据库连接
            try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
                // 关闭自动提交,以便在循环中使用事务
                conn.setAutoCommit(false);
                // 3. 准备SQL语句
                String sql = "INSERT INTO employees (id, name, age, department, hire_date) VALUES (?, ?, ?, ?, ?)";
                try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                    // 4. 遍历Excel行,从第二行开始(跳过标题行)
                    for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                        Row row = sheet.getRow(i);
                        if (row == null) continue;
                        Cell idCell = row.getCell(0);
                        Cell nameCell = row.getCell(1);
                        Cell ageCell = row.getCell(2);
                        Cell deptCell = row.getCell(3);
                        Cell dateCell = row.getCell(4);
                        // 设置参数
                        pstmt.setInt(1, (int) idCell.getNumericCellValue());
                        pstmt.setString(2, nameCell.getStringCellValue());
                        pstmt.setInt(3, (int) ageCell.getNumericCellValue());
                        pstmt.setString(4, deptCell.getStringCellValue());
                        // 处理日期
                        if (dateCell.getCellType() == CellType.NUMERIC) {
                            Date hireDate = dateCell.getDateCellValue();
                            pstmt.setDate(5, new java.sql.Date(hireDate.getTime()));
                        } else {
                            // 如果是字符串格式,需要手动解析
                            String dateStr = dateCell.getStringCellValue();
                            java.util.Date utilDate = sdf.parse(dateStr);
                            pstmt.setDate(5, new java.sql.Date(utilDate.getTime()));
                        }
                        // 5. 执行插入
                        pstmt.executeUpdate();
                        System.out.println("成功插入第 " + (i + 1) + " 行数据。");
                    }
                    // 6. 提交事务
                    conn.commit();
                    System.out.println("所有数据已成功导入数据库!");
                } catch (Exception e) {
                    // 发生异常,回滚事务
                    conn.rollback();
                    System.err.println("导入过程中发生错误,已回滚。");
                    e.printStackTrace();
                }
            }
        } catch (IOException | SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

批量插入 (High-Performance Approach)

这是处理大量数据(如上万行)的最佳实践,它通过 addBatch()executeBatch() 将多个 SQL 语句一次性发送给数据库执行,极大地减少了网络开销。

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExcelToOracleBatch {
    private static final String DB_URL = "jdbc:oracle:thin:@your_hostname:your_port:your_service_name";
    private static final String DB_USER = "your_username";
    private static final String DB_PASSWORD = "your_password";
    // 每批量插入1000条数据后执行一次
    private static final int BATCH_SIZE = 1000;
    public static void main(String[] args) {
        String excelFilePath = "path/to/your/employees.xlsx";
        try (FileInputStream fis = new FileInputStream(excelFilePath);
             Workbook workbook = new XSSFWorkbook(fis)) {
            Sheet sheet = workbook.getSheetAt(0);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
                conn.setAutoCommit(false); // 关闭自动提交,使用手动事务
                String sql = "INSERT INTO employees (id, name, age, department, hire_date) VALUES (?, ?, ?, ?, ?)";
                try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                    int count = 0;
                    // 从第二行开始遍历
                    for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                        Row row = sheet.getRow(i);
                        if (row == null)
分享:
扫描分享到社交APP
上一篇
下一篇