關於spring框架JdbcTemplate中的命令模式


前面已經說過命令模式,現在我們來看看spring框架中JdbcTemplate中使用的命令模式

首先先注入jdbctemplate 調用 queryForObject 方法

其實每個方法底層實現都一樣,就用這個舉例吧。點進去這個方法,一路跟進去,找到最深那個query方法

在中間一直都在構建查詢需要的參數,可以跳過,最深的query方法如下

@Override
    @Nullable
    public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException {
        Assert.notNull(sql, "SQL must not be null");
        Assert.notNull(rse, "ResultSetExtractor must not be null");
        if (logger.isDebugEnabled()) {
            logger.debug("Executing SQL query [" + sql + "]");
        }

        class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
            @Override
            @Nullable
            public T doInStatement(Statement stmt) throws SQLException {
                ResultSet rs = null;
                try {
                    rs = stmt.executeQuery(sql);
                    return rse.extractData(rs);
                }
                finally {
                    JdbcUtils.closeResultSet(rs);
                }
            }
            @Override
            public String getSql() {
                return sql;
            }
        }

        return execute(new QueryStatementCallback());
    }

這里面有個內部類  QueryStatementCallback  實現了  StatementCallback 接口

而這個接口只有一個方法

    @Nullable
    T doInStatement(Statement stmt) throws SQLException, DataAccessException;

通過類圖可以看到這個接口還有好幾個具體實現類

 上面說的QueryStatementCallback 只是其中一個,然后我們看看這個類具體實現方法  doInStatement 

本質上就是調用這個方法的參數的 executeQuery 方法 執行sql。

最后就是創建了這個內部類的實例傳給 execute方法 ,點進去,

 1   @Override
 2     @Nullable
 3     public <T> T execute(StatementCallback<T> action) throws DataAccessException {
 4         Assert.notNull(action, "Callback object must not be null");
 5 
 6         Connection con = DataSourceUtils.getConnection(obtainDataSource());
 7         Statement stmt = null;
 8         try {
 9             stmt = con.createStatement();
10             applyStatementSettings(stmt);
11             T result = action.doInStatement(stmt);
12             handleWarnings(stmt);
13             return result;
14         }
15         catch (SQLException ex) {
16             // Release Connection early, to avoid potential connection pool deadlock
17             // in the case when the exception translator hasn't been initialized yet.
18             String sql = getSql(action);
19             JdbcUtils.closeStatement(stmt);
20             stmt = null;
21             DataSourceUtils.releaseConnection(con, getDataSource());
22             con = null;
23             throw translateException("StatementCallback", sql, ex);
24         }
25         finally {
26             JdbcUtils.closeStatement(stmt);
27             DataSourceUtils.releaseConnection(con, getDataSource());
28         }
29     }

第11行,就是調用真正內部類的實現,在調用之前,需要構建方法所需參數stmt , 然后返回結果

那怎么和命令模式聯系起來呢?我們來和命令模式5種角色,對號入座:

Command 其實 就是  StatementCallback ,里面的doInStatement就是 命令方法。

CommandImpl  就是  QueryStatementCallback ,由命令的具體實現去調用真正的執行方法,真正的執行方法就是stmt的executeQuery()。

Receiver 呢?jdbctemplate 是沒有具體的,但是我們可以把 Statement 看做是這個receiver ,前面的命令模式說的是,命令的具體實現擁有接收者,並通過構造方法賦值,而template 它是把接收者當作參數傳遞,我覺得本質是一樣的

  因為之前實例化命令的具體實現時,傳入接收者,當然先的構造一個接收者,而template 也是一樣,先構造statement 然后傳入。

Invoker 就相當於  public <T> T execute(StatementCallback<T> action) throws DataAccessException 這個方法。

Client 就相當於我們自己開發的應用程序。

可以看出這個invokrer 也是傳入不同的具體命令,執行不同的 命令,達到不一樣的結果。

參考了一些大佬的博客,結合自己的見解,如果有不對的地方,請指出哈。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM