`
squll369
  • 浏览: 109472 次
  • 性别: 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讲义

    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 web的旅游网站源码(含数据库脚本).rar

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

    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