Spring JDBC最佳实践(2)

fmms 12年前
     <b>使用DataSourceUtils进行Connection的管理</b>    <br /> 由    <a href="http://www.open-open.com/lib/view/open1325676513734.html" target="_blank">上节代码</a>可知,JdbcTemplate在获取Connection的时候,并不是直接调用DataSource的getConnection(),而是调用了如下的代码:    <br />    <pre class="brush:java; toolbar: true; auto-links: false;">  Connection con = DataSourceUtils.getConnection(getDataSource());</pre>    <p></p> 为什么要这么做呢?    <br /> 实际上,如果对于一个功能带一的JdbcTemplate来说,调用如下的代码就够了:    <br />    <pre class="brush:java; toolbar: true; auto-links: false;">  Connection con = dataSource.getConnection();</pre>    <p></p> 只不过,spring所提供的JdbcTemplate要关注更多的东西,所以,在从dataSource取得连接的时候,需要多做一些事情。    <br />    <p>org.springframework.jdbc.datasource.DataSourceUtils所提供的方法,用来从指定的DataSource中获取或者释放连接,它会将取得的Connection绑定到当前的线程,以便在使用Spring所提供的统一事务抽象层进行事务管理的时候使用。</p>    <p><b>为什么要使用NativeJdbcExtractor</b><br /> 在execute()方法中可以看到:<br /> </p>    <pre class="brush:java; toolbar: true; auto-links: false;">   if (this.nativeJdbcExtractor != null &&      this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {     conToUse = this.nativeJdbcExtractor.getNativeConnection(con);    }</pre>    <p></p>    <pre class="brush:java; toolbar: true; auto-links: false;">if (this.nativeJdbcExtractor != null) {     stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);    }</pre>    <p></p> 通过该处理,获取的将是相应的驱动程序所提供的实现类,而不是相应的代理对象。    <br /> JdbcTemplate内部定义了一个NativeJdbcExtractor类型的实例变量:    <br />    <pre class="brush:java; toolbar: true; auto-links: false;"> /** Custom NativeJdbcExtractor */  private NativeJdbcExtractor nativeJdbcExtractor;</pre>    <p></p> 当我们想用驱动对象所提供的原始API的时候,可以通过JdbcTemplate的如下代码:    <br />    <pre class="brush:java; toolbar: true; auto-links: false;"> public void setNativeJdbcExtractor(NativeJdbcExtractor extractor) {   this.nativeJdbcExtractor = extractor;  }</pre>这样将会获取真正的目标对象而不是代理对象。    <br />    <p>spring默认提供面向Commons DBCP、C3P0、Weblogic、Websphere等数据源的<span style="line-height:18px;font-family:'Courier New', Arial;white-space:pre;font-size:12px;">NativeJdbcExtractor的实现类: CommonsDbcpNativeJdbcExtractor:为Jakarta Commons DBCP数据库连接池所提供的NativeJdbcExtractor实现类 C3P0NativeJdbcExtractor:为C3P0数据库连接池所提供的NativeJdbcExtractor实现类 WebLogicNativeJdbcExtractor:为Weblogic所准备的NativeJdbcExtractor实现类</span></p>    <p><span style="line-height:18px;font-family:'Courier New', Arial;white-space:pre;font-size:12px;">WebSphereNativeJdbcExtractor:为WebSphere所准备的NativeJdbcExtractor实现类</span></p>    <p><span style="font-family:''Courier New', Arial';"><span style="line-height:18px;white-space:pre;font-size:12px;"><b>控制JdbcTemplate的行为</b> JdbcTemplate在使用Statement或者PreparedStatement等进行具体的数据操作之前,会调用如下的代码:</span></span></p>    <pre class="brush:java; toolbar: true; auto-links: false;"> 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());  }</pre>    <p>这样便可以设置Statement每次抓取的行数 等等。</p>    <p><b>SQLException到DataAccessException的转译</b> 因为JdbcTemplate直接操作的是JDBC API,所以它需要捕获在此期间可能发生的SQLException,处理的宗旨是将SQLException 转译到spring的数据访问异常层次体系,以统一数据访问异常的处理方式,这个工作主要是交给了SQLExceptionTranslator,该 接口的定义如下:</p>    <pre class="brush:java; toolbar: true; auto-links: false;">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>    <p></p> 该接口有两个主要的实现类,SQLErrorCodeSQLExceptionTranslator和SQLStateSQLExceptionTranslator,如下所示:    <img style="width:658px;height:193px;" alt="Spring JDBC最佳实践(2)" src="https://simg.open-open.com/show/276a4cefd578031e27ccc5baef8359fd.jpg" />    <p></p>