`
squll369
  • 浏览: 108691 次
  • 性别: 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 jdbc 分页例子

    此外,代码还提到了使用接口回调的特性,这意味着可能有其他类或方法会监听 `JdbcUtil` 的操作,例如在执行查询前后的处理逻辑,但具体的实现没有在这个例子中给出。 总的来说,这个简单的Java JDBC分页示例主要...

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

    本主题将深入探讨Spring框架中的JdbcTemplate组件,以及模板模式和回调机制的概念。 **1. Spring JdbcTemplate** JdbcTemplate是Spring提供的一个用于简化数据库操作的API,它是Spring对JDBC(Java Database ...

    JDBC+JQuery+ajax小例子

    5. Ajax的回调函数接收到服务器响应,根据返回的消息更新页面显示,例如显示登录成功或失败的信息。 6. 对于删除功能,用户选择一条记录并触发删除操作,同样使用Ajax向Servlet发送请求。 7. Servlet接收到请求后,...

    Java端 ajax简单入门例子

    6. **Ajax回调**:前端的JavaScript代码会在XMLHttpRequest对象的onreadystatechange事件中监听服务器的响应。当状态变为4(表示请求已完成)且status为200(表示成功)时,读取responseText属性获取服务器返回的...

    java实用经典编程100例(已分类)

    例子将展示其在处理集合和回调函数中的应用。 13. **并发编程**:Java并发库提供了高级并发工具,如ExecutorService和Future。示例可能涵盖并发设计模式。 14. **Java 8及以后的新特性**:Java 8引入了日期时间API...

    java2应用编程150例.rar

    14. ** Lambda表达式**:Java 8引入了Lambda表达式,简化了函数式编程,实例将展示如何使用它来处理集合和实现回调。 15. **流与并行流**:Java 8的流API简化了对集合的操作,而并行流则支持高效的并行计算,这两者...

    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...

    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_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经典学习实例:100个源码.rar

    这些实例可能会展示如何使用函数接口和lambda表达式来实现回调函数或简化代码。 4. **网络编程**:Java的`java.net`包提供了实现网络通信的功能,如Socket编程、ServerSocket、URL连接等。实例可能涵盖客户端和...

    基于Java web的旅游网站源码(含数据库脚本).rar

    这涉及API调用、交易状态回调等。 7. **测试**: - 单元测试和集成测试确保代码质量和功能正确性,如使用JUnit进行Java代码测试,Selenium进行Web应用的功能测试。 8. **部署**: - 项目可能在Tomcat、Jetty等...

    疯狂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 ...

    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 Lambda 编程之道

    例如,可以通过适配器模式将旧的回调接口转换为新的Lambda形式,从而提高代码的可维护性。 ```java // 假设有一个旧的回调接口 interface Callback { void process(String data); } // 使用适配器模式将Lambda...

    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...

    Java+ajax写的登录实例

    5. Ajax回调函数接收到响应后,解析JSON数据,根据结果更新UI,如显示登录成功或错误信息。 通过这个实例,初学者可以深入理解Java和Ajax的协作,学习如何构建一个实时反馈的Web应用。同时,这也有助于理解前后端...

    java实例100例

    实例会展示如何使用Lambda简化匿名内部类和回调函数。 14. **并发编程**:Java提供了丰富的并发工具类,如ExecutorService、Future和Callable。实例将展示如何有效管理并发任务。 通过"Java实例100例",你将能够...

Global site tag (gtag.js) - Google Analytics