spring的JdbcTemplate封裝了jdbc的實現,下面通過源代碼看一下其實現
1,一個執行Statement回調的接口

public?interface?StatementCallback?
{
??????Object?doInStatement(Statement?stmt)?throws?SQLException,?DataAccessException;
????}

??public?Object?execute(StatementCallback?action)?throws?DataAccessException?
{
??????//獲取線程的同一個連接
??????Connection?con?=?DataSourceUtils.getConnection(getDataSource());
??????Statement?stmt?=?null;

??????try?
{
??????????Connection?conToUse?=?con;
??
??????????if?(this.nativeJdbcExtractor?!=?null?&&
??????????????this.nativeJdbcExtractor.

??????????????isNativeConnectionNecessaryForNativeStatements())?
{
??????????????//通過特定廠商的特定方法,獲取特定廠商的連接
??????????????conToUse?=?this.nativeJdbcExtractor.getNativeConnection(con);
??????????}
??????????stmt?=?conToUse.createStatement();
??????????//計算并調用stmt.setQueryTimeout(..)
??????????DataSourceUtils.applyTransactionTimeout(stmt,?getDataSource());
??????????Statement?stmtToUse?=?stmt;

??????????if?(this.nativeJdbcExtractor?!=?null)?
{
??????????????stmtToUse?=?this.nativeJdbcExtractor.getNativeStatement(stmt);
??????????}
??????????//執行回調
??????????Object?result?=?action.doInStatement(stmtToUse);
??????????SQLWarning?warning?=?stmt.getWarnings();
??????????throwExceptionOnWarningIfNotIgnoringWarnings(warning);
??????????return?result;

??????}?catch?(SQLException?ex)?
{
??????????//對異常進行轉譯,所有拋出異常都繼承DataAccessException這個非受控異常
??????????throw?getExceptionTranslator().translate(
??????????????????"executing?StatementCallback",?getSql(action),?ex);

??????}?finally?
{
??????????JdbcUtils.closeStatement(stmt);
??????????DataSourceUtils.releaseConnection(con,?getDataSource());
??????}
??}2,一個StatementCallback預定義實現,提供query接口

public?Object?query(final?String?sql,?final?ResultSetExtractor?rse)?throws?DataAccessException?
{

???if?(sql?==?null)?
{
??????????throw?new?InvalidDataAccessApiUsageException("SQL?must?not?be?null");
??????}
??????if?(JdbcUtils.countParameterPlaceholders(sql,?'?',?"'\"")?>?0)?{
??????????throw?new?InvalidDataAccessApiUsageException(
??????????????????"Cannot?execute?["?+?sql?+
??????????????????"]?as?a?static?query:?it?contains?bind?variables");
??????}

??????if?(logger.isDebugEnabled())?
{
??????????logger.debug("Executing?SQL?query?["?+?sql?+?"]");
??????}
??????//執行回調的內部類

??????class?QueryStatementCallback?implements?StatementCallback,?SqlProvider?
{

??????????public?Object?doInStatement(Statement?stmt)?throws?SQLException?
{
??????????????ResultSet?rs?=?null;

??????????????try?
{

??????????????????if?(getFetchSize()?>?0)?
{
??????????????????????stmt.setFetchSize(getFetchSize());
??????????????????}

??????????????????if?(getMaxRows()?>?0)?
{
??????????????????????stmt.setMaxRows(getMaxRows());
??????????????????}
??????????????????rs?=?stmt.executeQuery(sql);
??????????????????ResultSet?rsToUse?=?rs;

??????????????????if?(nativeJdbcExtractor?!=?null)?
{
??????????????????????rsToUse?=?nativeJdbcExtractor.getNativeResultSet(rs);
??????????????????}
??????????????????//又一個回調
??????????????????return?rse.extractData(rsToUse);

??????????????}?finally?
{
??????????????????JdbcUtils.closeResultSet(rs);
??????????????}
??????????}


??????????public?String?getSql()?
{
??????????????return?sql;
??????????}
??????}
??????return?execute(new?QueryStatementCallback());
??}3,看一下一個預定義的ResultSetExtractor實現

??private?static?class?RowCallbackHandlerResultSetExtractor?implements?ResultSetExtractor?
{

????????private?final?RowCallbackHandler?rch;


????????public?RowCallbackHandlerResultSetExtractor(RowCallbackHandler?rch)?
{
????????????this.rch?=?rch;
????????}


????????public?Object?extractData(ResultSet?rs)?throws?SQLException?
{
????????????//利用RowCallbackHandler處理resultset,返回處理結果List

????????????while?(rs.next())?
{
????????????????this.rch.processRow(rs);
????????????}

????????????if?(this.rch?instanceof?ResultReader)?
{
????????????????return?((ResultReader)?this.rch).getResults();
????????????}

????????????else?
{
????????????????return?null;
????????????}
????????}
????}
????

????public?interface?ResultReader?extends?RowCallbackHandler?
{
?????

????????/**?*//**
?????????*?Return?all?results,?disconnected?from?the?JDBC?ResultSet.
?????????*?Never?returns?null;?returns?the?empty?collection?if?there
?????????*?were?no?results.
?????????*/
????????List?getResults();

????}
????
????

????public?class?RowMapperResultReader?implements?ResultReader?
{


????????/**?*//**?List?to?save?results?in?*/
????????private?final?List?results;
????

????????/**?*//**?The?RowMapper?implementation?that?will?be?used?to?map?rows?*/
????????private?final?RowMapper?rowMapper;
????

????????/**?*//**?The?counter?used?to?count?rows?*/
????????private?int?rowNum?=?0;
????

????????/**?*//**
?????????*?Create?a?new?RowMapperResultReader.
?????????*?@param?rowMapper?the?RowMapper?which?creates?an?object?for?each?row
?????????*/

????????public?RowMapperResultReader(RowMapper?rowMapper)?
{
????????????this(rowMapper,?0);
????????}
????

????????/**?*//**
?????????*?Create?a?new?RowMapperResultReader.
?????????*?@param?rowMapper?the?RowMapper?which?creates?an?object?for?each?row
?????????*?@param?rowsExpected?the?number?of?expected?rows
?????????*?(just?used?for?optimized?collection?handling)
?????????*/

????????public?RowMapperResultReader(RowMapper?rowMapper,?int?rowsExpected)?
{
????????????//?Use?the?more?efficient?collection?if?we?know?how?many?rows?to?expect:
????????????//?ArrayList?in?case?of?a?known?row?count,?LinkedList?if?unknown
????????????this.results?=?(rowsExpected?>?0)???(List)?new?ArrayList(rowsExpected)?:?(List)?new?LinkedList();
????????????this.rowMapper?=?rowMapper;
????????}
????

????????public?void?processRow(ResultSet?rs)?throws?SQLException?
{
????????????this.results.add(this.rowMapper.mapRow(rs,?this.rowNum++));
????????}
????

????????public?List?getResults()?
{
????????????return?this.results;
????????}

????}?4,連接是如何獲取的

????public?abstract?class?DataSourceUtils?
{
????????
????????//
..
????????

????????public?static?Connection?doGetConnection(DataSource?dataSource)?throws?SQLException?
{
????????????Assert.notNull(dataSource,?"No?DataSource?specified");
????????????//利用ThreadLocal,獲取當前線程對應dataSource的connection封裝---ConnectionHolder
????????????ConnectionHolder?conHolder?=?(ConnectionHolder)?TransactionSynchronizationManager.getResource(dataSource);

????????????if?(conHolder?!=?null)?
{
????????????????conHolder.requested();
????????????????return?conHolder.getConnection();
????????????}
????????????//如果conHolder為空,為當前線程獲取一個新連接,并設置ThreadLocal
????????????logger.debug("Opening?JDBC?Connection");
????????????Connection?con?=?dataSource.getConnection();
????????????

????????????if?(TransactionSynchronizationManager.isSynchronizationActive())?
{
????????????????logger.debug("Registering?transaction?synchronization?for?JDBC?Connection");
????????????????//?Use?same?Connection?for?further?JDBC?actions?within?the?transaction.
????????????????//?Thread-bound?object?will?get?removed?by?synchronization?at?transaction?completion.
????????????????conHolder?=?new?ConnectionHolder(con);
????????????????conHolder.setSynchronizedWithTransaction(true);
????????????????conHolder.requested();
????????????????TransactionSynchronizationManager.registerSynchronization(
????????????????????????new?ConnectionSynchronization(conHolder,?dataSource));
????????????????TransactionSynchronizationManager.bindResource(dataSource,?conHolder);
????????????}
????
????????????return?con;
????????}
????????//注意異常的改變

????????public?static?Connection?getConnection(DataSource?dataSource)?throws?CannotGetJdbcConnectionException?
{

????????????try?
{
????????????????return?doGetConnection(dataSource);
????????????}

????????????catch?(SQLException?ex)?
{
????????????????throw?new?CannotGetJdbcConnectionException("Could?not?get?JDBC?Connection",?ex);
????????????}
????????}
????}5,getResource和bindResource實現

????public?abstract?class?TransactionSynchronizationManager?
{
????????
????????//
..
????????
????????private?static?final?ThreadLocal?resources?=?new?ThreadLocal();

????????private?static?final?ThreadLocal?synchronizations?=?new?ThreadLocal();
????????

????????public?static?Object?getResource(Object?key)?
{
????????????Map?map?=?(Map)?resources.get();

????????????if?(map?==?null)?
{
????????????????return?null;
????????????}
????????????Object?value?=?map.get(key);

????????????if?(value?!=?null?&&?logger.isDebugEnabled())?
{
????????????????logger.debug("Retrieved?value?["?+?value?+?"]?for?key?["?+?key?+?"]?bound?to?thread?["?+
????????????????????????Thread.currentThread().getName()?+?"]");
????????????}
????????????return?value;
????????}

????????public?static?void?bindResource(Object?key,?Object?value)?throws?IllegalStateException?
{
????????????Map?map?=?(Map)?resources.get();
????????????//?set?ThreadLocal?Map?if?none?found

????????????if?(map?==?null)?
{
????????????????map?=?new?HashMap();
????????????????resources.set(map);
????????????}

????????????if?(map.containsKey(key))?
{
????????????????throw?new?IllegalStateException("Already?value?["?+?map.get(key)?+?"]?for?key?["?+?key?+
????????????????????????"]?bound?to?thread?["?+?Thread.currentThread().getName()?+?"]");
????????????}
????????????map.put(key,?value);

????????????if?(logger.isDebugEnabled())?
{
????????????????logger.debug("Bound?value?["?+?value?+?"]?for?key?["?+?key?+?"]?to?thread?["?+
????????????????????????Thread.currentThread().getName()?+?"]");
????????????}
????????}
????}6,ConnectionHolder?類

public?class?ConnectionHolder?extends?ResourceHolderSupport?
{

????private?final?ConnectionHandle?connectionHandle;

????private?Connection?currentConnection;


????/**?*//**
?????*?Create?a?new?ConnectionHolder?for?the?given?ConnectionHandle.
?????*?@param?connectionHandle?the?ConnectionHandle?to?hold
?????*/

????public?ConnectionHolder(ConnectionHandle?connectionHandle)?
{
????????this.connectionHandle?=?connectionHandle;
????}


????/**?*//**
?????*?Create?a?new?ConnectionHolder?for?the?given?JDBC?Connection,
?????*?wrapping?it?with?a?SimpleConnectionHandle.
?????*?@param?connection?the?JDBC?Connection?to?hold
?????*?@see?SimpleConnectionHandle
?????*/

????public?ConnectionHolder(Connection?connection)?
{
????????this.connectionHandle?=?new?SimpleConnectionHandle(connection);
????}


????/**?*//**
?????*?Return?the?ConnectionHandle?held?by?this?ConnectionHolder.
?????*/

????public?ConnectionHandle?getConnectionHandle()?
{
????????return?connectionHandle;
????}


????/**?*//**
?????*?Return?the?current?Connection?held?by?this?ConnectionHolder.
?????*?<p>This?will?be?the?same?Connection?until?<code>released</code>
?????*?gets?called?on?the?ConnectionHolder,?which?will?reset?the
?????*?held?Connection,?fetching?a?new?Connection?on?demand.
?????*?@see?ConnectionHandle#getConnection()
?????*?@see?#released()
?????*/

????public?Connection?getConnection()?
{

????????if?(this.currentConnection?==?null)?
{
????????????this.currentConnection?=?this.connectionHandle.getConnection();
????????}
????????return?this.currentConnection;
????}


????/**?*//**
?????*?Releases?the?current?Connection?held?by?this?ConnectionHolder.
?????*?<p>This?is?necessary?for?ConnectionHandles?that?expect?"Connection?borrowing",
?????*?where?each?returned?Connection?is?only?temporarily?leased?and?needs?to?be
?????*?returned?once?the?data?operation?is?done,?to?make?the?Connection?available
?????*?for?other?operations?within?the?same?transaction.?This?is?the?case?with
?????*?JDO?2.0?DataStoreConnections,?for?example.
?????*?@see?org.springframework.orm.jdo.DefaultJdoDialect#getJdbcConnection
?????*/

????public?void?released()?
{
????????super.released();

????????if?(this.currentConnection?!=?null)?
{
????????????this.connectionHandle.releaseConnection(this.currentConnection);
????????????this.currentConnection?=?null;
????????}
????}

}
public?class?SimpleConnectionHandle?implements?ConnectionHandle?
{

????private?final?Connection?connection;


????/**?*//**
?????*?Create?a?new?SimpleConnectionHandle?for?the?given?Connection.
?????*?@param?connection?the?JDBC?Connection
?????*/

????public?SimpleConnectionHandle(Connection?connection)?
{
????????this.connection?=?connection;
????}


????public?Connection?getConnection()?
{
????????return?connection;
????}


????public?void?releaseConnection(Connection?con)?
{
????}


????public?String?toString()?
{
????????return?"SimpleConnectionHandle:?"?+?this.connection;
????}

}