论坛首页 Java企业应用论坛

Spring DAO "JdbcTemplate.execute()" 的疑惑 ?

浏览 5142 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-07-08  
先来看看 JdbcTemplate.execute(final String sql) 这个方法的原代码:

class JdbcTemplate {
    public void execute(final String sql) {
		class ExecuteStatementCallback implements StatementCallback, SqlProvider {
            //method in StatementCallback
			public Object doInStatement(Statement stmt) throws SQLException {
				stmt.execute(sql);
				return null;
			}
            //method in SqlProvider
			public String getSql() {
				return sql;
			}
		}
		execute(new ExecuteStatementCallback()); 
    }

	public Object execute(StatementCallback action) throws DataAccessException {
		Assert.notNull(action, "Callback object must not be null");

		Connection con = DataSourceUtils.getConnection(getDataSource());
        ...
		Statement stmt = con.createStatement();
        ...
        Object result = action.doInStatement(stmtToUse);
		return result;		
    }
}


执行一条 sql 语句, 进行了以下几步:
1) 先 创建一个 内部类 ExecuteStatementCallback,
    这个ExecuteStatementCallback实现了2个接口:
        A) StatementCallback: 提供了1个方法,根据传入的 Statement 参数, 来执行查询, 
        B) SqlProvider: 提供1个方法, 返回sql语句。   
           //返回参数里面的Sql语句

2) 调用另外一个方法 execute(StatementCallback action)
   在这个方法里面, 创建 Statement 对象, 并执行Sql 语句.

   Object result = StatementCallback.doInStatement(Statement);
  
在这里, 这个 ExecuteStatementCallback 是不是太多余了?
他实现了2个接口, 每个接口分别实现1个方法, 一个用来返回参数里面的 Sql 语句, 
一个用来执行Sql 语句的方法, 而执行Sql 语句所需要的 Statement 也是在外面创建好了传给他, 

执行1个Sql 查询, 需要1个 Statement, 1 Sql 语句,
Statement.execute(Sql)
就这么简单, 

外面已经创建好了 Statement, Sql 直接从参数里面获取就可以,
为什么 JdbcTemplate 在执行一个 Sql 语句时, 需要创建这个ExecuteStatementCallback ?
在Execute(Sql) 里面再调用另外一个 Execute(...) 这个很好理解,外面也通常这么做, 可是中间再引入一个 ExecuteStatementCallback 来获取外部传给他的 Sql,  Statement, 再由他来执行这条Sql 语句。 究竟为什么?
实在百思不得其解。。。。 

我直接在一个方法里面做:
public void execute(final String sql) {
    Connection con = DataSourceUtils.getConnection(getDataSource());
    ...
    Statement stmt = con.createStatement();
    stmt.execute(sql);
}


这样不是简单得多?

或者说, 按照他的逻辑, 再调用另外一个 execute(.. sql) 来真正执行。
public void execute(final String sql) {
    execute(sql...); 
}

public void execute(final String sql...) {
    Connection con = DataSourceUtils.getConnection(getDataSource());
    ...
    Statement stmt = con.createStatement();
    ...
    Object result = stme.execute(sql);
    return result;		
}



这样, 结构也不复杂, 

作者究竟是如何设计的? 
这背后的设计思想是什么 ?
Comand 模式 ? Proxy 模式 ? Mediator ?
。。。

   发表时间:2007-07-08  
spring源码中经常出现的template method模式与callback的结合,往往使用匿名内部类来处理,至于带来的好处,将可变部分与不可变部分的分离,比如这里Object execute(..方法定义了执行sql的基本骨架,可变的部分是执行statement的哪个方法等,这个可变部分推迟到内部类来决定,比如ExecuteStatementCallback 内部类中的stmt.execute(sql),比如你再看看update方法,变化的只是实现回调接口的内部类,同时也避免了代码重复。template method可以看成是OO化的callback。
0 请登录后投票
   发表时间:2007-07-09  
看名字就知道是Template模式啦,哈
0 请登录后投票
   发表时间:2007-07-09  
这么说也有道理,

感觉为了设计方法的完美, 调用一个方法就需要额外创建一个对象,  不知道创建对象对系统的消耗大不大,
当然调用一次当然不大, 要是系统中很多这种情况, 都是这种模版方法,不知道会不会对性能有影响?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics