`
squll369
  • 浏览: 106488 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

Java回调机制,利用回调写的JDBC 访问例子

阅读更多

 

    首先说说为什么要用到回调这个方式,

    我们在日常生活和工作中,有一种情况是这样的,做一件事,但是这件事中有些步骤是不确定如何做的,但是可以先约定好怎么做.对于程序来说,就是有一段业务,其中有几段小逻辑不确定如何做,但是我们可以先定义好一些方法(统一的参数和返回值)对应这些逻辑, 具体这些逻辑的实现交给具体执行的代码去实现.

    下面举个例子,JDBC 访问,假设我们都用PreparedStatement来处理SQL, 我们都要初始化连接,初始化PreparedStatement,封装PreparedStatement插入SQL参数,执行SQL,获得ResultSet,封装ResultSet成我们要的对象,关闭连接,其中封装PreparedStatement插入SQL参数和封装ResultSet成我们要的对象是不确定的,我们就可以把这2步定义成回调函数,交给具体执行代码去做.

    根据上面说的,我们可以定一个JdbcCallback接口来定义这个回调函数,

 

package com.balance.easycalendar.dao.template;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import com.balance.easycalendar.to.BaseTO;

public interface JdbcCallback {
	
	public List<BaseTO> packResult(ResultSet rs) throws SQLException;
	public void packParams(PreparedStatement stmt) throws SQLException;
}

 

再定义一个JdbcCallbackTemplate来执行具体的方法,其中引用一个JdbcCallback来完成不确定的步骤,

package com.balance.easycalendar.dao.template;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;

import com.balance.easycalendar.dao.exception.DAOException;
import com.balance.easycalendar.to.BaseTO;
import com.balance.easycalendar.util.MessageProperties;

public class JdbcCallbackTemplate {

	private JdbcCallback temp;
	
	public void setTemp(JdbcCallback temp) {
		this.temp = temp;
	}

	protected String url;
	protected String username;
	protected String password;
	protected String driver;
	
	private PreparedStatement stmt = null;
	private Connection con = null;
	
	public JdbcCallbackTemplate(){
		MessageProperties pro = MessageProperties.getInstance("jdbc.properties");
		
		url = pro.getValue("db.url");
		driver = pro.getValue("db.driver");
		username = pro.getValue("db.username");
		password = pro.getValue("db.password");	
	}
	
	public List<BaseTO> query(String sql) throws DAOException{
		try{
			Class.forName(driver);
			con = DriverManager.getConnection(url, username, password);
	
			stmt = con.prepareStatement(sql);
			temp.packParams(stmt);
			
			ResultSet rs = stmt.executeQuery();
			
			return temp.packResult(rs);
			
		}catch(Exception e){
			throw new DAOException(e);
		}finally{
			try{
				stmt.close();
				con.close();
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	
	public boolean excute(String sql) throws DAOException{
		try{
			Class.forName(driver);
			con = DriverManager.getConnection(url, username, password);
	
			stmt = con.prepareStatement(sql);
			temp.packParams(stmt);
			
			return stmt.execute();
			
		}catch(Exception e){
			throw new DAOException(e);
		}finally{
			try{
				stmt.close();
				con.close();
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	
}

    这个Template定义了2个方法, excute用来执行增加,修改,删除等,query用来执行查询,在这2个方法里,封装参数,封装result都不确定,所以用了上面定义的回调函数来实行,具体实现交给具体的实现类去做.(MessageProperties 是我写的一个资源引用类,可以参考我的另一篇blog:利用多例模式编写配置文件读取器 )

 

   下面我们看看具体的实现,

    BaseDAO里实例化一个jdbcCallbackTemplate

package com.balance.easycalendar.dao;

import com.balance.easycalendar.dao.template.JdbcCallbackTemplate;
import com.balance.easycalendar.util.MessageProperties;


public abstract class BaseDAO {
	
		
	protected JdbcCallbackTemplate jdbcCallbackTemplate = new JdbcCallbackTemplate();
	
	public String getSql(String sqlId){
		MessageProperties pro = MessageProperties.getInstance("sqls.properties");	
		return pro.getValue(sqlId);
	}
}
 

定义一个TaskDAO,用来执行具体的数据库访问.首先给jdbcCallbackTemplate注入实例化的JdbcCallback(实现具体的回调函数),然后就可以调用Template里的query和excute方法了.

package com.balance.easycalendar.dao;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.balance.easycalendar.dao.exception.DAOException;
import com.balance.easycalendar.dao.template.JdbcCallback;
import com.balance.easycalendar.dao.template.JdbcCallbackAdapter;
import com.balance.easycalendar.to.BaseTO;
import com.balance.easycalendar.to.TaskTO;

public class TaskDAO extends BaseDAO{

	public TaskTO getTask(final String taskId) throws DAOException {
		jdbcCallbackTemplate.setTemp(new JdbcCallback(){
			@Override
			public void packParams(PreparedStatement stmt) throws SQLException {
				stmt.setString(1, taskId);		
			}

			@Override
			public List<BaseTO> packResult(ResultSet rs) throws SQLException {
				List<BaseTO> tasks = new ArrayList<BaseTO>();		
				while (rs.next()) {
					TaskTO taskTO = new TaskTO();
					taskTO.setTaskId(rs.getString("TASK_ID"));
					taskTO.setTaskName(rs.getString("TASK_NAME"));
					taskTO.setTaskDesc(rs.getString("TASK_DESC"));
					
					tasks.add(taskTO);
				}
				
				return tasks;
			}
		});
	
		List<BaseTO> tasks = jdbcCallbackTemplate.query(getSql("task.search.bytaskid"));
		return (TaskTO)tasks.get(0);
	}
	
	public boolean insertTask(final String taskId, final String taskName, final String taskDesc) throws DAOException {
		jdbcCallbackTemplate.setTemp(new JdbcCallbackAdapter(){

			@Override
			public void packParams(PreparedStatement stmt) throws SQLException {
				stmt.setString(1, taskId);
				stmt.setString(2, taskName);
				stmt.setString(3, taskDesc);
			}			
		});
		
		return jdbcCallbackTemplate.excute(getSql("task.insert"));
	}
	
	public boolean delTask(final String taskId) throws DAOException {
		jdbcCallbackTemplate.setTemp(new JdbcCallbackAdapter(){

			@Override
			public void packParams(PreparedStatement stmt) throws SQLException {
				stmt.setString(1, taskId);
			}			
		});
		
		return jdbcCallbackTemplate.excute(getSql("task.delete.bytaskid"));
	}

}

 

sql我也用MessageProperties来读取了,定义在一个单独的properties文件里,

task.search.bytaskid = select TASK_ID,TASK_NAME,TASK_DESC from TB_TASKS where TASK_ID = ?
task.insert = insert into TB_TASKS (TASK_ID,TASK_NAME,TASK_DESC) values (?,?,?)
task.delete.bytaskid = Delete from TB_TASKS where TASK_ID = ?

 

JdbcCallbackAdapte是JdbcCallback的一个默认适配器,提供了packResult一个空实现,因为excute不需要封装result对象。

 

好了,这个例子就是这样了.

分享到:
评论

相关推荐

    java 编程入门思考

    A.3.4 编写回调函数 A.3.5 其他J/Direct特性 A.4 本原接口(RNI) A.4.1 RNI总结 A.5 Java/COM集成 A.5.1 COM基础 A.5.2 MS Java/COM集成 A.5.3 用Java设计COM服务器 A.5.4 用Java设计COM客户 A.5.5 ActiveX/Beans...

    Java初学者入门教学

    A.3.4 编写回调函数 A.3.5 其他J/Direct特性 A.4 本原接口(RNI) A.4.1 RNI总结 A.5 Java/COM集成 A.5.1 COM基础 A.5.2 MS Java/COM集成 A.5.3 用Java设计COM服务器 A.5.4 用Java设计COM客户 A.5.5 ActiveX/Beans...

    java联想(中文)

    A.3.4 编写回调函数 A.3.5 其他J/Direct特性 A.4 本原接口(RNI) A.4.1 RNI总结 A.5 Java/COM集成 A.5.1 COM基础 A.5.2 MS Java/COM集成 A.5.3 用Java设计COM服务器 A.5.4 用Java设计COM客户 A.5.5 ActiveX/Beans...

    JAVA_Thinking in Java

    A.3.4 编写回调函数 A.3.5 其他J/Direct特性 A.4 本原接口(RNI) A.4.1 RNI总结 A.5 Java/COM集成 A.5.1 COM基础 A.5.2 MS Java/COM集成 A.5.3 用Java设计COM服务器 A.5.4 用Java设计COM客户 A.5.5 ActiveX/Beans...

    Thinking in Java简体中文(全)

    A.3.4 编写回调函数 A.3.5 其他J/Direct特性 A.4 本原接口(RNI) A.4.1 RNI总结 A.5 Java/COM集成 A.5.1 COM基础 A.5.2 MS Java/COM集成 A.5.3 用Java设计COM服务器 A.5.4 用Java设计COM客户 A.5.5 ActiveX/Beans...

    疯狂JAVA讲义

    6.7.6 闭包(Closure)和回调 215 6.8 枚举类 217 6.8.1 手动实现枚举类 217 6.8.2 枚举类入门 219 6.8.3 枚举类的属性、方法和构造器 220 6.8.4 实现接口的枚举类 223 6.8.5 包含抽象方法的枚举类 224 6.9 ...

    JAVA_Thinking in Java(中文版 由yyc,spirit整理).chm

    A.3.4 编写回调函数 A.3.5 其他J/Direct特性 A.4 本原接口(RNI) A.4.1 RNI总结 A.5 Java/COM集成 A.5.1 COM基础 A.5.2 MS Java/COM集成 A.5.3 用Java设计COM服务器 A.5.4 用Java设计COM客户 A.5.5 ActiveX/Beans...

    Thinking in Java 中文第四版+习题答案

    A.3.4 编写回调函数 A.3.5 其他J/Direct特性 A.4 本原接口(RNI) A.4.1 RNI总结 A.5 Java/COM集成 A.5.1 COM基础 A.5.2 MS Java/COM集成 A.5.3 用Java设计COM服务器 A.5.4 用Java设计COM客户 A.5.5 ActiveX/Beans...

    Thinking in Java(中文版 由yyc,spirit整理).chm

    A.3.4 编写回调函数 A.3.5 其他J/Direct特性 A.4 本原接口(RNI) A.4.1 RNI总结 A.5 Java/COM集成 A.5.1 COM基础 A.5.2 MS Java/COM集成 A.5.3 用Java设计COM服务器 A.5.4 用Java设计COM客户 A.5.5 ActiveX/Beans...

    Think in Java(中文版)chm格式

    A.3.4 编写回调函数 A.3.5 其他J/Direct特性 A.4 本原接口(RNI) A.4.1 RNI总结 A.5 Java/COM集成 A.5.1 COM基础 A.5.2 MS Java/COM集成 A.5.3 用Java设计COM服务器 A.5.4 用Java设计COM客户 A.5.5 ...

    Java开发技术大全 电子版

    4.10.3抽象方法与回调函数171 4.11最终类与最终方法173 4.12接口与多重继承174 4.12.1接口的定义174 4.12.2接口的继承175 4.12.3接口的实现177 4.13内部类179 4.13.1内部类的定义179 4.13.2内部类访问外部类...

    ThinkInJava

    A.3.4 编写回调函数 A.3.5 其他J/Direct特性 A.4 本原接口(RNI) A.4.1 RNI总结 A.5 Java/COM集成 A.5.1 COM基础 A.5.2 MS Java/COM集成 A.5.3 用Java设计COM服务器 A.5.4 用Java设计COM客户 A.5.5 ActiveX/Beans...

    JAVA程序设计教程

    Java程序.............................................................................................6 1.3.1 Java程序的结构 ...........................................................................

    thinkinjava

    A.3.4 编写回调函数 A.3.5 其他J/Direct特性 A.4 本原接口(RNI) A.4.1 RNI总结 A.5 Java/COM集成 A.5.1 COM基础 A.5.2 MS Java/COM集成 A.5.3 用Java设计COM服务器 A.5.4 用Java设计COM客户 A.5.5 ActiveX/Beans...

    J2EE中文版指南 CHM格式 带全文检索

    确定应用程序客户端的回调处理机制 232 六.EIS(Enterprise Information System)层安全 232 配置契约 232 容器管理的契约 232 组件管理的契约 233 配置资源适配器安全 233 七.传递安全身份 234 配置组件使用的...

    Spring.3.x企业应用开发实战(完整版).part2

    8.3.1 使用模板和回调机制 8.3.2 Spring为不同持久化技术所提供的模板类 8.4 数据源 8.4.1 配置一个数据源 8.4.2 获取JNDI数据源 8.4.3 Spring的数据源实现类 8.5 小结 第9章 Spring的事务管理 9.1 数据库事务基础...

    Spring3.x企业应用开发实战(完整版) part1

    8.3.1 使用模板和回调机制 8.3.2 Spring为不同持久化技术所提供的模板类 8.4 数据源 8.4.1 配置一个数据源 8.4.2 获取JNDI数据源 8.4.3 Spring的数据源实现类 8.5 小结 第9章 Spring的事务管理 9.1 数据库事务基础...

    Spring-Reference_zh_CN(Spring中文参考手册)

    12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7. 声明式的事务划分 12.2.8. 事务管理策略 12.2.9. 容器资源 vs 本地资源 12.2.10. 在应用服务器...

    Spring 2.0 开发参考手册

    12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7. 声明式的事务划分 12.2.8. 事务管理策略 12.2.9. 容器资源 vs 本地资源 12.2.10. 在应用...

Global site tag (gtag.js) - Google Analytics