首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

Java POI 讀取 Excel 導入 DB2:從 Demo 到通用轉換器的演進思路

     編輯:DB2 教學

專案背景

需讀取 Excel 文件將數據入庫 DB2,後續供報表查詢。功能簡單,選型 Apache POI(信任度高、社區活躍)。

Demo 代碼核心邏輯


public class POITest {
  private static Connection conn;
  private static Statement stmt;

  // 1. DB2 連接(兩種驅動擇一)
  private static boolean connectDB2() {
    try {
      // JCC 驅動 (推薦)
      Class.forName("com.ibm.db2.jcc.DB2Driver");
      String url = "jdbc:db2://192.168.0.1:50000/dbname";
      // Legacy 驅動
      // Class.forName("com.ibm.db2.jdbc.app.DB2Driver").newInstance();
      // String url = "jdbc:db2:njtcdata";
      conn = DriverManager.getConnection(url, "username", "password");
      stmt = conn.createStatement();
      return true;
    } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); return false; }
  }

  // 2. POI 讀取 Excel → 逐行 INSERT
  private static boolean readExcelToDB2() {
    try (POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream("c:\\test.xls"));
         HSSFWorkbook wb = new HSSFWorkbook(fs)) {
      HSSFSheet sheet = wb.getSheetAt(0);
      for (int i = 0; i <= sheet.getLastRowNum(); i++) {
        HSSFRow row = sheet.getRow(i);
        String name = row.getCell(0).getStringCellValue();
        int id = (int) row.getCell(1).getNumericCellValue();
        String sql = "INSERT INTO TEST(ID, NAME) VALUES(" + id + ",'" + name + "')";
        stmt.executeUpdate(sql);
      }
      return true;
    } catch (IOException | SQLException e) { e.printStackTrace(); return false; }
  }

  public static void main(String[] args) {
    if (connectDB2() && readExcelToDB2()) System.out.println("導入成功");
    else System.out.println("導入失敗");
  }
}

Demo 痛點:代碼「硬編碼」無法複用

  • 針對單一 Excel 結構寫死欄位索引、SQL、表名
  • 新增一張表就要複製一個類,維護成本極高
  • 無類型映射、無數據校驗、無批次提交、無異常重試

通用轉換器設計藍圖

核心抽象層


interface RowMapper {
  T mapRow(Row row, int rowNum) throws Exception;
}

interface SqlGenerator {
  String generateInsert(T entity);
  String generateBatchInsert(List entities);  // 批次優化
}

class ExcelImportEngine {
  void importExcel(File file, RowMapper mapper, SqlGenerator gen, 
                   int batchSize, Connection conn) { ... }
}

配置驅動而非代碼驅動

配置項說明
sheet 選擇名稱/索引/正則
表頭行號自動偵測或指定
欄位映射Excel 欄名/索引 → 實體屬性 → DB 欄名
類型轉換String/Number/Date/Boolean 自定義轉換器
校驗規則非空、長度、格式、外鍵存在性
目標表單表/多表/臨時表+MERGE
批次大小預設 1000,可調
錯誤策略跳過/終止/記錄錯誤行繼續

關鍵效能優化

  • PreparedStatement + addBatch:替代 Statement 拼接 SQL,防注入、複用計劃
  • 游標流式讀取:XSSFReader (SAX) 或 SXSSFWorkbook 處理大文件不 OOM
  • 並行導入:按 Sheet/行範圍分區,多線程寫入不同分區表
  • LOAD 替代 INSERT:超大量時生成 DEL 文件 → LOAD FROM ...

技術選型補充

場景推薦庫理由
.xls (BIFF8)POI HSSF成熟穩定
.xlsx (OOXML)POI XSSF / SXSSF支援流式寫入大文件
超大文件/低記憶體EasyExcel (阿里)佔用記憶體極低、API 友好
純讀取/高性能fastexcel零依賴、極快

總結

Demo 走通「連接 → 讀取 → 寫入」最短路徑;通用轉換器將「映射、校驗、批次、錯誤處理、效能」外部化配置,實現一套引擎跑遍所有 Excel 導入場景。下一步:抽取配置 Schema、實現映射 DSL、接入監控告警,沉澱為組件庫服務全團隊。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved