Spring 学习 JdbcTemplate,模板模式,回调

先通过一个小例子,简单使用一下。

 

配置文件 applicationContext.xml

 

<beans  default-autowire ="autodetect"> 
     <bean id ="dataSource"  class ="org.apache.commons.dbcp.BasicDataSource">  
         <property name ="driverClassName">  
             <value>oracle.jdbc.driver.OracleDriver</value>  
         </property>  
         <property name ="url">  
             <value>jdbc:oracle:thin:@localhost:1521:orcl</value> 
          </property> 
         <property name="username"> 
             <value>username</value> 
         </property> 
         <property name="password"> 
             <value>password</value> 
         </property> 
         <property name="maxActive"> 
             <value>10</value> 
         </property> 
         <property name="maxIdle"> 
             <value>2</value> 
         </property> 
     </bean> 

     <bean id ="JdbcTemplate"
         class ="org.springframework.jdbc.core.JdbcTemplate"> 
         <property name ="dataSource"> 
             <ref bean ="dataSource"  /> 
         </property> 
     </bean> 
 </beans> 

 

程序

	public static void main(String[] args) {
		
		ClassPathResource res = new ClassPathResource("applicationContext.xml");
		XmlBeanFactory factory = new XmlBeanFactory(res);
		JdbcTemplate jdbcTemplate = (JdbcTemplate) factory
				.getBean("JdbcTemplate");
	 
		jdbcTemplate
				.update("delete from TB_USER where ID= 466 ");
	}

 

只需要一句代码,  就完成了我们关心的 jdbc 操作。

 

F3,看下 jdbcTemplate.update 的实现,

 

	public int update(final String sql) throws DataAccessException {
		Assert.notNull(sql, "SQL must not be null");
		if (logger.isDebugEnabled()) {
			logger.debug("Executing SQL update [" + sql + "]");
		}

		class UpdateStatementCallback implements StatementCallback, SqlProvider {
			public Object doInStatement(Statement stmt) throws SQLException {
				int rows = stmt.executeUpdate(sql);
				if (logger.isDebugEnabled()) {
					logger.debug("SQL update affected " + rows + " rows");
				}
				return new Integer(rows);
			}
			public String getSql() {
				return sql;
			}
		}
		return ((Integer) execute(new UpdateStatementCallback())).intValue();
	}

 

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

		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();
			applyStatementSettings(stmt);
			Statement stmtToUse = stmt;
			if (this.nativeJdbcExtractor != null) {
				stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);
			}
			Object result = action.doInStatement(stmtToUse);
			handleWarnings(stmt.getWarnings());
			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.
			JdbcUtils.closeStatement(stmt);
			stmt = null;
			DataSourceUtils.releaseConnection(con, getDataSource());
			con = null;
			throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
		}
		finally {
			JdbcUtils.closeStatement(stmt);
			DataSourceUtils.releaseConnection(con, getDataSource());
		}
	}

这里就用到了 Template 设计模式,估计Spring 的这个模块叫 JdbcTemplate 的原因也在于此。

 

 action.doInStatement(stmtToUse);

 执行主体逻辑,

 

 至于 之后的 catch,finally 等,都是无聊又必须有的 开闭Connection 之类的操作,

 Spring 把他们固定成模板代码,都不用动他们了,

 只需实现Spring 留给我们的一句 :  action.doInStatement(stmtToUse) 

 

 Spring 是使用 Java 回调 实现的。

 

update 方法里, 初始化了一个类, UpdateStatementCallback ,

UpdateStatementCallback  里,doInStatement 方法里,就是要执行的主体代码,

但 update 方法并没有直接调用doInStatement ,

而是把 整个UpdateStatementCallback  作为参数,传给了 execute 方法,

再由 execute 调用 UpdateStatementCallback   的 doInStatement ,

 

很绕,总结一下就是,A 里边有个B,A委托C调用自己的B,

 那为什么A自己不调呢,上边的例子就是一个原因,

A 是我们负责写的类,C 是Spring,

因为 调用B 之前和之后 要做额外操作, 是很烦的工作,所以A就把活推给C了

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值