zoukankan      html  css  js  c++  java
  • 关于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 也是传入不同的具体命令,执行不同的 命令,达到不一样的结果。

    参考了一些大佬的博客,结合自己的见解,如果有不对的地方,请指出哈。

  • 相关阅读:
    PLSQL_Oracle Trigger触发器的基本概念和用法
    PLSQL_Oracle Object所有数据库对象类型汇总和简解(概念)
    OAF_EO系列2
    OAF_EO系列1
    OAF_OAF Debug And Log调试和记录工具的详解(案例)
    OAF_OAF Exception Handling异常处理(概念)
    DBA_FND Load程式迁移工具介绍和应用(案例)
    Form_Form标准控件Folder开发解析(案列)
    BEvent_标准BusinessEvent用以监控供应商的修改(案例)
    PLSQL_Oracle Logon Trigger的建立
  • 原文地址:https://www.cnblogs.com/longyao/p/12576119.html
Copyright © 2011-2022 走看看