posts - 29, comments - 0, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          模板模式在Spring 中的應用

          Posted on 2007-05-28 15:34 change 閱讀(158) 評論(0)  編輯  收藏

          在spring里面我們一般是這樣來使用模板模式的:

          JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
          jdbcTemplate.update("UPDATE user SET age = 10 WHERE id = 'erica'");

          或者:

          JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
          jdbcTemplate
          .update(
          "UPDATE user SET age = ? WHERE id = ?",
          new PreparedStatementSetter() {
          public void setValues(PreparedStatementSetter ps)
          throws SQLException {
          ps.setInt(1, 18);
          ps.setString(2, "erica");
          }
          }
          );

          那么具體在spring里面他是怎么運作的呢?

          下面以query查詢?yōu)槔?/font>

          public class JdbcTemplate extends JdbcAccessor implements JdbcOperations, InitializingBean {

          。。。。。。。。。。。。。。。。。。。。。。。。。

          protected Object query(
             PreparedStatementCreator psc, final PreparedStatementSetter pss, final ResultSetExtractor rse)
             throws DataAccessException {
            if (logger.isDebugEnabled()) {
             String sql = getSql(psc);
             logger.debug("Executing SQL query" + (sql != null ? " [" + sql  + "]" : ""));
            }
            return execute(psc, new PreparedStatementCallback() {

          //此處以 PreparedStatementCallback 為參數(shù)調用 execute()方法,在execute()方法里面回調傳入的方法。在回調方法里面即根據(jù)傳入的 PreparedStatement 執(zhí)行 查詢操作,返回結果。而 PreparedStatement  的獲取是在調用回調方法的客戶端實現(xiàn)即在execute()方法里面獲取,并作為參數(shù)傳給回調方法。
             public Object doInPreparedStatement(PreparedStatement ps) throws SQLException {
              ResultSet rs = null;
              try {
               if (pss != null) {
                pss.setValues(ps);
               }
               if (getFetchSize() > 0) {
                ps.setFetchSize(getFetchSize());
               }
               rs = ps.executeQuery();
               ResultSet rsToUse = rs;
               if (nativeJdbcExtractor != null) {
                rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
               }
               return rse.extractData(rsToUse);
              }
              finally {
               JdbcUtils.closeResultSet(rs);
               if (pss instanceof ParameterDisposer) {
                ((ParameterDisposer) pss).cleanupParameters();
               }
              }
             }
            });
           }

          那么在execue()方法里面是怎樣回調的呢?下面看看execue()方法:

          public Object execute(PreparedStatementCreator psc, PreparedStatementCallback action) {
            Connection con = DataSourceUtils.getConnection(getDataSource());
            PreparedStatement ps = null;
            try {
             Connection conToUse = con;
             if (this.nativeJdbcExtractor != null &&
               this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativePreparedStatements()) {
              conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
             }
             ps = psc.createPreparedStatement(conToUse);
             DataSourceUtils.applyTransactionTimeout(ps, getDataSource());
             PreparedStatement psToUse = ps;
             if (this.nativeJdbcExtractor != null) {
              psToUse = this.nativeJdbcExtractor.getNativePreparedStatement(ps);
             }
             Object result = action.doInPreparedStatement(psToUse);
             SQLWarning warning = ps.getWarnings();
             throwExceptionOnWarningIfNotIgnoringWarnings(warning);
             return result;
            }
            catch (SQLException ex) {
             throw getExceptionTranslator().translate(
               "executing PreparedStatementCallback [" + psc + "]", getSql(psc), ex);
            }
            finally {
             if (psc instanceof ParameterDisposer) {
              ((ParameterDisposer) psc).cleanupParameters();
             }
             JdbcUtils.closeStatement(ps);
             DataSourceUtils.closeConnectionIfNecessary(con, getDataSource());
            }
           }

          添加刪除的操作類似,只是他們的實現(xiàn)都在以execute命名的方法里面。

          public void execute(final String sql) throws DataAccessException {
            if (logger.isDebugEnabled()) {
             logger.debug("Executing SQL statement [" + sql + "]");
            }
            class ExecuteStatementCallback implements StatementCallback, SqlProvider {
             public Object doInStatement(Statement stmt) throws SQLException {
              stmt.execute(sql);
              return null;
             }
             public String getSql() {
              return sql;
             }
            }
            execute(new ExecuteStatementCallback());
           }

          public Object execute(final StatementCallback action) {
            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();
             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) {
             throw getExceptionTranslator().translate("executing StatementCallback", getSql(action), ex);
            }
            finally {

          //這里就是我們自己寫程序的時候需要寫的關于數(shù)據(jù)庫鏈接的關閉操作
             JdbcUtils.closeStatement(stmt);
             DataSourceUtils.closeConnectionIfNecessary(con, getDataSource());
            }
           }

          主站蜘蛛池模板: 眉山市| 民县| 北碚区| 溧水县| 包头市| 河池市| 会泽县| 大丰市| 大宁县| 澄迈县| 江达县| 广灵县| 高台县| 上饶市| 齐河县| 克东县| 大埔县| 谷城县| 普安县| 连江县| 鄂托克旗| 齐齐哈尔市| 东至县| 沧州市| 宁河县| 六枝特区| 宁阳县| 逊克县| 布拖县| 灵宝市| 商都县| 通许县| 玛多县| 南陵县| 台南县| 灵宝市| 呼图壁县| 获嘉县| 山丹县| 景洪市| 土默特右旗|