首先说说为什么要用到回调这个方式,
我们在日常生活和工作中,有一种情况是这样的,做一件事,但是这件事中有些步骤是不确定如何做的,但是可以先约定好怎么做.对于程序来说,就是有一段业务,其中有几段小逻辑不确定如何做,但是我们可以先定义好一些方法(统一的参数和返回值)对应这些逻辑, 具体这些逻辑的实现交给具体执行的代码去实现.
下面举个例子,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对象。
好了,这个例子就是这样了.
分享到:
相关推荐
此外,代码还提到了使用接口回调的特性,这意味着可能有其他类或方法会监听 `JdbcUtil` 的操作,例如在执行查询前后的处理逻辑,但具体的实现没有在这个例子中给出。 总的来说,这个简单的Java JDBC分页示例主要...
本主题将深入探讨Spring框架中的JdbcTemplate组件,以及模板模式和回调机制的概念。 **1. Spring JdbcTemplate** JdbcTemplate是Spring提供的一个用于简化数据库操作的API,它是Spring对JDBC(Java Database ...
5. Ajax的回调函数接收到服务器响应,根据返回的消息更新页面显示,例如显示登录成功或失败的信息。 6. 对于删除功能,用户选择一条记录并触发删除操作,同样使用Ajax向Servlet发送请求。 7. Servlet接收到请求后,...
6. **Ajax回调**:前端的JavaScript代码会在XMLHttpRequest对象的onreadystatechange事件中监听服务器的响应。当状态变为4(表示请求已完成)且status为200(表示成功)时,读取responseText属性获取服务器返回的...
例子将展示其在处理集合和回调函数中的应用。 13. **并发编程**:Java并发库提供了高级并发工具,如ExecutorService和Future。示例可能涵盖并发设计模式。 14. **Java 8及以后的新特性**:Java 8引入了日期时间API...
14. ** Lambda表达式**:Java 8引入了Lambda表达式,简化了函数式编程,实例将展示如何使用它来处理集合和实现回调。 15. **流与并行流**:Java 8的流API简化了对集合的操作,而并行流则支持高效的并行计算,这两者...
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...
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...
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...
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...
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...
这些实例可能会展示如何使用函数接口和lambda表达式来实现回调函数或简化代码。 4. **网络编程**:Java的`java.net`包提供了实现网络通信的功能,如Socket编程、ServerSocket、URL连接等。实例可能涵盖客户端和...
这涉及API调用、交易状态回调等。 7. **测试**: - 单元测试和集成测试确保代码质量和功能正确性,如使用JUnit进行Java代码测试,Selenium进行Web应用的功能测试。 8. **部署**: - 项目可能在Tomcat、Jetty等...
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 ...
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...
例如,可以通过适配器模式将旧的回调接口转换为新的Lambda形式,从而提高代码的可维护性。 ```java // 假设有一个旧的回调接口 interface Callback { void process(String data); } // 使用适配器模式将Lambda...
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...
5. Ajax回调函数接收到响应后,解析JSON数据,根据结果更新UI,如显示登录成功或错误信息。 通过这个实例,初学者可以深入理解Java和Ajax的协作,学习如何构建一个实时反馈的Web应用。同时,这也有助于理解前后端...
实例会展示如何使用Lambda简化匿名内部类和回调函数。 14. **并发编程**:Java提供了丰富的并发工具类,如ExecutorService、Future和Callable。实例将展示如何有效管理并发任务。 通过"Java实例100例",你将能够...