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

Spring 整合 JDBC 實戰:從 JdbcTemplate 到最佳實踐模式

     編輯:Java 相關知識

Spring 提供了強大的 JDBC 抽象層,消除樣板代碼,讓數據庫操作更簡潔、安全。本文系統講解三大核心模板類的遞進關係、基礎用法、DAO 支持類以及聲明式配置最佳實踐。

一、三大 JDBC 模板類遞進關係

模板類核心特性適用場景
JdbcTemplate最基礎模板,使用索引參數 ? 綁定值,封裝連接獲取、語句創建、資源釋放、異常轉換全流程。簡單查詢、更新、批量操作,無需命名參數時。
NamedParameterJdbcTemplate內部持有 JdbcTemplate,支持 命名參數 (如 :name),可讀性更強,支持 Map/List 批量綁定。SQL 參數較多、動態構建 SQL、需提高可維護性時。
SimpleJdbcTemplate (已過時)利用 Java 5 泛型、可變參數、自動拆裝箱簡化 API,內部委託 NamedParameterJdbcTemplate。Spring 3.1+ 已標記 @Deprecated,建議直接使用 JdbcTemplate 或 NamedParameterJdbcTemplate 配合 Java 8+ 語法。

遞進關係:SimpleJdbcTemplate > NamedParameterJdbcTemplate > JdbcTemplate (功能遞增)。現代項目推薦直接使用前兩者。

二、基礎用法:手動構建 JdbcTemplate

// 1. 配置數據源 (示例使用 DriverManagerDataSource,生產環境請用連接池)
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/sampledb");
ds.setUsername("root");
ds.setPassword("");

// 2. 創建 JdbcTemplate 並注入數據源
JdbcTemplate jdbc = new JdbcTemplate();
jdbc.setDataSource(ds);

// 3. 執行 DDL / DML
String sql = "CREATE TABLE t_user1 (user_id INT PRIMARY KEY, user_name VARCHAR(60))";
jdbc.execute(sql); // 執行任意 SQL

// 4. 參數化查詢/更新
jdbc.update("INSERT INTO t_user1 VALUES (?, ?)", 1, "Alice");
List<Map<String, Object>> users = jdbc.queryForList("SELECT * FROM t_user1");

注意:DriverManagerDataSource 非真正連接池,每次獲取連接都新建物理連接,生產嚴禁使用,請改用 HikariCP、Druid、DBCP2 等。

三、進階模式:JdbcDaoSupport 消除樣板代碼

若在每個 DAO 中重複 new JdbcTemplate()、setDataSource(),代碼極其冗餘。Spring 提供 JdbcDaoSupport 基類:

public class ForumDAO extends JdbcDaoSupport {
    public void initDb() {
        String sql = "CREATE TABLE t_user1 (user_id INT PRIMARY KEY, user_name VARCHAR(60))";
        getJdbcTemplate().execute(sql); // 直接使用模板
    }
}

只需在 Spring 容器中為 DAO 注入 dataSource 或 jdbcTemplate,基類自動完成初始化。

四、聲明式配置最佳實踐 (XML / Java Config)

1. XML 配置範例

<beans xmlns="https://www.springframework.org/schema/beans"
       xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="https://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 1. 真正的連接池數據源 (以 DBCP2 為例) -->
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/sampledb"/>
        <property name="username" value="root"/>
        <property name="password" value=""/>
        <property name="initialSize" value="5"/>
        <property name="maxTotal" value="20"/>
    </bean>

    <!-- 2. JdbcTemplate Bean -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 3. DAO Bean,繼承 JdbcDaoSupport 自動獲得模板 -->
    <bean id="forumDAO" class="dao.jdbc.ForumDAO">
        <property name="dataSource" ref="dataSource"/> <!-- 或注入 jdbcTemplate -->
    </bean>
</beans>

2. 現代 Java Config 寫法 (推薦)

@Configuration
@ComponentScan("dao.jdbc")
public class JdbcConfig {

    @Bean
    public DataSource dataSource() {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl("jdbc:mysql://localhost:3306/sampledb");
        ds.setUsername("root");
        ds.setPassword("");
        return ds;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
    // DAO 直接 @Autowired JdbcTemplate 或繼承 JdbcDaoSupport
}

五、核心操作 API 速查

  • 更新/寫入:update(sql, params...)、batchUpdate(sqlList)、execute(sql)
  • 查詢單值:queryForObject(sql, params, ReturnType)
  • 查詢單行映射對象:queryForObject(sql, params, RowMapper<T>)
  • 查詢列表:query(sql, params, RowMapper<T>)、queryForList(sql, params)
  • 分頁/大數據集:配合 ResultSetExtractor 或 PagingQueryProvider (Spring Data JDBC)。

六、異常處理與事務管理

Spring 將 JDBC 的 SQLException 轉換為非受檢的 DataAccessException 體系,統一異常處理。配合 @Transactional 或 DataSourceTransactionManager 實現聲明式事務:

@Transactional
public void transfer(Long fromId, Long toId, BigDecimal amount) {
    jdbc.update("UPDATE account SET balance = balance - ? WHERE id = ?", amount, fromId);
    jdbc.update("UPDATE account SET balance = balance + ? WHERE id = ?", amount, toId);
}

七、總結與建議

  1. 首選 NamedParameterJdbcTemplate:SQL 可讀性高,參數綁定靈活。
  2. 數據源必須用生產級連接池 (HikariCP 首選)。
  3. DAO 層使用 Java Config + @Repository + @Autowired JdbcTemplate,拒絕 XML 與 JdbcDaoSupport 混用。
  4. 複雜查詢/動態 SQL:考慮引入 MyBatis 或 JOOQ,JdbcTemplate 適合中簡單場景。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved