• 关于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方法 ,点进去,

         @Override
         @Nullable
         public <T> T execute(StatementCallback<T> action) throws DataAccessException {
             Assert.notNull(action, "Callback object must not be null");
     
             Connection con = DataSourceUtils.getConnection(obtainDataSource());
             Statement stmt = null;
             try {
                 stmt = con.createStatement();
                 applyStatementSettings(stmt);
                 T result = action.doInStatement(stmt);
                 handleWarnings(stmt);
                 return result;
             }
             catch (SQLException ex) {
                 // Release Connection early, to avoid potential connection pool deadlock
                 // in the case when the exception translator hasn't been initialized yet.
                 String sql = getSql(action);
                 JdbcUtils.closeStatement(stmt);
                 stmt = null;
                 DataSourceUtils.releaseConnection(con, getDataSource());
                 con = null;
                 throw translateException("StatementCallback", sql, ex);
             }
             finally {
                 JdbcUtils.closeStatement(stmt);
                 DataSourceUtils.releaseConnection(con, getDataSource());
             }
         }

    第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 也是传入不同的具体命令,执行不同的 命令,达到不一样的结果。

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

    转载于:https://www.cnblogs.com/longyao/p/12576119.html

  • 相关阅读:
    实验一、DOS使用命令实验
    实验三、进程调度模拟程序
    实验四、存储管理
    实验二、作业调度模拟程序
    简单的DOS命令
    结构化方法和面向对象方法的比较
    jstree 取消选中父节点
    T4 模板代码生成
    基于Open XML 导出数据到Excel
    菜单(列存储转为行存储)
  • 原文地址:https://www.cnblogs.com/it-deepinmind/p/13265368.html
Copyright © 2020-2023  润新知