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

          模板模式在Spring 中的應用

          Posted on 2007-05-28 15:34 change 閱讀(156) 評論(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查詢為例:

          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 為參數調用 execute()方法,在execute()方法里面回調傳入的方法。在回調方法里面即根據傳入的 PreparedStatement 執行 查詢操作,返回結果。而 PreparedStatement  的獲取是在調用回調方法的客戶端實現即在execute()方法里面獲取,并作為參數傳給回調方法。
             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());
            }
           }

          添加刪除的操作類似,只是他們的實現都在以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 {

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

          主站蜘蛛池模板: 宣化县| 金阳县| 裕民县| 肇州县| 正镶白旗| 循化| 剑河县| 健康| 莱西市| 胶州市| 广昌县| 于都县| 扬州市| 荣成市| 百色市| 珠海市| 彭州市| 来凤县| 东乡县| 时尚| 上思县| 绥滨县| 邢台市| 阳朔县| 新昌县| 松潘县| 涡阳县| 六枝特区| 宣恩县| 庄浪县| 阳曲县| 涟水县| 新田县| 康马县| 西乌| 阿图什市| 孝义市| 昌黎县| 平和县| 文登市| 建湖县|