Spring JDBC最佳實踐(2)

fmms 12年前發布 | 82K 次閱讀 Spring JDBC JEE框架

使用DataSourceUtils進行Connection的管理
上節代碼可知,JdbcTemplate在獲取Connection的時候,并不是直接調用DataSource的getConnection(),而是調用了如下的代碼:

       Connection con = DataSourceUtils.getConnection(getDataSource());

為什么要這么做呢?
實際上,如果對于一個功能帶一的JdbcTemplate來說,調用如下的代碼就夠了:
       Connection con = dataSource.getConnection();

只不過,spring所提供的JdbcTemplate要關注更多的東西,所以,在從dataSource取得連接的時候,需要多做一些事情。

org.springframework.jdbc.datasource.DataSourceUtils所提供的方法,用來從指定的DataSource中獲取或者釋放連接,它會將取得的Connection綁定到當前的線程,以便在使用Spring所提供的統一事務抽象層進行事務管理的時候使用。

為什么要使用NativeJdbcExtractor
在execute()方法中可以看到:

           if (this.nativeJdbcExtractor != null &&
                    this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {
                conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
            }

if (this.nativeJdbcExtractor != null) {
                stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);
            }

通過該處理,獲取的將是相應的驅動程序所提供的實現類,而不是相應的代理對象。
JdbcTemplate內部定義了一個NativeJdbcExtractor類型的實例變量:
   /** Custom NativeJdbcExtractor */
    private NativeJdbcExtractor nativeJdbcExtractor;

當我們想用驅動對象所提供的原始API的時候,可以通過JdbcTemplate的如下代碼:
   public void setNativeJdbcExtractor(NativeJdbcExtractor extractor) {
        this.nativeJdbcExtractor = extractor;
    }
這樣將會獲取真正的目標對象而不是代理對象。

spring默認提供面向Commons DBCP、C3P0、Weblogic、Websphere等數據源的NativeJdbcExtractor的實現類: CommonsDbcpNativeJdbcExtractor:為Jakarta Commons DBCP數據庫連接池所提供的NativeJdbcExtractor實現類 C3P0NativeJdbcExtractor:為C3P0數據庫連接池所提供的NativeJdbcExtractor實現類 WebLogicNativeJdbcExtractor:為Weblogic所準備的NativeJdbcExtractor實現類

WebSphereNativeJdbcExtractor:為WebSphere所準備的NativeJdbcExtractor實現類

控制JdbcTemplate的行為 JdbcTemplate在使用Statement或者PreparedStatement等進行具體的數據操作之前,會調用如下的代碼:

   protected void applyStatementSettings(Statement stmt) throws SQLException {
        int fetchSize = getFetchSize();
        if (fetchSize > 0) {
            stmt.setFetchSize(fetchSize);
        }
        int maxRows = getMaxRows();
        if (maxRows > 0) {
            stmt.setMaxRows(maxRows);
        }
        DataSourceUtils.applyTimeout(stmt, getDataSource(), getQueryTimeout());
    }

這樣便可以設置Statement每次抓取的行數 等等。

SQLException到DataAccessException的轉譯 因為JdbcTemplate直接操作的是JDBC API,所以它需要捕獲在此期間可能發生的SQLException,處理的宗旨是將SQLException 轉譯到spring的數據訪問異常層次體系,以統一數據訪問異常的處理方式,這個工作主要是交給了SQLExceptionTranslator,該 接口的定義如下:

package org.springframework.jdbc.support;

import java.sql.SQLException;

import org.springframework.dao.DataAccessException;

/**

*

  • @author Rod Johnson
  • @author Juergen Hoeller
  • @see org.springframework.dao.DataAccessException */ public interface SQLExceptionTranslator {
DataAccessException translate(String task, String sql, SQLException ex);

}</pre>

該接口有兩個主要的實現類,SQLErrorCodeSQLExceptionTranslator和SQLStateSQLExceptionTranslator,如下所示: Spring JDBC最佳實踐(2)

 本文由用戶 fmms 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!