dingfirst

          On the?。遥铮幔?/p>

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            8 隨筆 :: 2 文章 :: 3 評論 :: 0 Trackbacks
          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;
          ????}


          }
          posted on 2006-07-13 10:39 dingfirst 閱讀(1494) 評論(1)  編輯  收藏

          評論

          # re: spring對jdbc的封裝 2006-10-24 12:55 111
          11111  回復  更多評論
            


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 宁海县| 兴安盟| 商洛市| 分宜县| 武山县| 绥宁县| 佛山市| 九龙坡区| 藁城市| 永定县| 通许县| 北票市| 盈江县| 东方市| 新野县| 灵寿县| 衡阳县| 合江县| 桐庐县| 沈阳市| 汉阴县| 武夷山市| 南投县| 卫辉市| 峨眉山市| 嘉善县| 潼关县| 海伦市| 保靖县| 噶尔县| 富平县| 阳曲县| 滨海县| 老河口市| 宣威市| 沅陵县| 龙山县| 桑植县| 绍兴县| 清河县| 前郭尔|