首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring JDBC 抽象框架實戰:從傳統 JDBC 到 JdbcTemplate 的最佳實踐

     編輯:Java 相關知識

傳統 JDBC 痛點回顧

// 典型樣板代碼
Connection con = null; PreparedStatement ps = null; ResultSet rs = null;
try {
    con = getConnection();
    ps = con.prepareStatement(sql);
    rs = ps.executeQuery();
    while (rs.next()) { list.add(rs.getString(1)); }
} catch (SQLException e) { e.printStackTrace(); }
finally {
    try { rs.close(); ps.close(); con.close(); } catch (SQLException e) { e.printStackTrace(); }
}

四大罪狀:資源管理樣板碼泛濫、`SQLException` 失去語義、錯誤碼跨資料庫不一致、業務邏輯被基礎設施代碼淹沒。

Spring JDBC 核心優勢

特性傳統 JDBCSpring JDBC
資源管理手動 try-finally模板模式自動釋放
異常體系單一 SQLException分層 `DataAccessException` 體系
資料映射手動 `rs.getXxx()``RowMapper` / `ResultSetExtractor`
DataSource 獲取硬編碼/單例IoC 容器注入
測試性難以 Mock易於單元測試 (嵌入式 DB)

核心組件架構


org.springframework.jdbc
├── core
│   ├── JdbcTemplate           # 核心模板類
│   ├── RowMapper              # 行映射策略介面
│   ├── RowCallbackHandler     # 流式處理回調
│   └── simple                 # SimpleJdbcInsert/Call 簡化 API
├── datasource
│   ├── DriverManagerDataSource # 簡單實現 (測試用)
│   └── ...                    # C3P0/DBCP/Hikari 整合
├── object                     # RDBMS Operation 物件化 (可重用、線程安全)
└── support                    # SQLErrorCodeSQLExceptionTranslator 等工具

快速上手:JdbcTemplate + RowMapper

1. 定義 DAO 介面

public interface TaskDao {
    List getTaskNames();
}

2. 實現類繼承 JdbcDaoSupport

public class TaskJdbcDao extends JdbcDaoSupport implements TaskDao {
    @Override
    public List getTaskNames() {
        return getJdbcTemplate().query(
            "SELECT task_name FROM tasks",
            new RowMapper() {
                @Override
                public String mapRow(ResultSet rs, int rowNum) throws SQLException {
                    return rs.getString(1);
                }
            }
        );
    }
}

3. Spring XML 配置 (IoC 注入 DataSource)

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
      destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
    <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
    <property name="username" value="scott"/>
    <property name="password" value="tiger"/>
</bean>

<bean id="taskDao" class="com.example.TaskJdbcDao">
    <property name="dataSource" ref="dataSource"/>
</bean>

4. 客戶端調用

ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
TaskDao dao = ctx.getBean("taskDao", TaskDao.class);
dao.getTaskNames().forEach(System.out::println);

進階:分層架構整合 (Service + DAO)

// Service 介面
public interface TaskService {
    List getTaskNames();
}

// Service 實現 - 依賴 DAO 介面
@Service
public class TaskServiceImpl implements TaskService {
    private TaskDao taskDao;
    
    @Autowired
    public void setTaskDao(TaskDao taskDao) { this.taskDao = taskDao; }
    
    @Override
    public List getTaskNames() { return taskDao.getTaskNames(); }
}

// XML 裝配
<bean id="taskService" class="com.example.TaskServiceImpl">
    <property name="taskDao" ref="taskDao"/>
</bean>

進階特性速覽

  • 命名參數:`NamedParameterJdbcTemplate` 支援 `:name` 風格 SQL,避免 `?` 位置錯誤。
  • 批次操作:`batchUpdate(sqlList)` / `batchUpdate(sql, batchArgs)` 大幅提升批量寫入效能。
  • LOB 處理:`LobHandler` / `LobCreator` 統一 Oracle/PostgreSQL/MySQL 大對象 API 差異。
  • 序列/自增 Key 獲取:`KeyHolder` + `PreparedStatementCreator` 統一獲取生成鍵。
  • 原生 JDBC 物件提取:`NativeJdbcExtractor` 穿透連線池代理,獲取 Oracle `oracle.sql.BLOB` 等專有類型。

異常轉換機制原理

  1. 捕獲 `SQLException`。
  2. 檢查 `DatabaseMetaData` 判斷資料庫產品 (Oracle/MySQL/PostgreSQL...)。
  3. 依據 `sql-error-codes.xml` 映射錯誤碼 → 具體 `DataAccessException` 子類 (`DataIntegrityViolationException`、`CannotAcquireLockException` 等)。
  4. 拋出 Spring 統一異常,上層捕獲業務語義異常而非 SQL 錯誤碼。

總結

Spring JDBC 以 模板模式消除樣板碼、異常體系賦予語義、IoC 實現鬆耦合,讓開發者聚焦 SQL 與業務映射。雖 ORM (Hibernate/JPA) 更主流,但對於複雜報表、批量處理、存儲過程調用、Legacy 系統改造,Spring JDBC 仍是輕量、可控、高效的首選利器。

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