前言
- 回调函数在框架中的使用是家常便饭,无论是前台框架还是后台框架,譬如,Jquery的Ajax函数就封装了回调的功能,Spring在整合Hibernate的时候也封装了回调的功能,那为什么要有回调那?回调函数到底有什么作用那?小编谈一下自己的见解。
回调函数的作用
- 为什么设置回调函数,这个问题困扰了好长一段时间,小编看了一些框架的源码后才恍然大明白,回调函数的作用。读者不用着急,先跟着我看个JS的小Demo,通过Demo来理解回调函数。
window.onload=function(){
//封装回调函数
function callBack(a,b){
alert(a);
b();
};
function testCallBack(){
//注意:此时将整个function(){}.....作为callBack函数的第二个参数
callBack("begin testCallback",function(){
alert("test callback success");
})
};
testCallBack();
}
提问
- 看完了这个小demo,如果读者还有点迷糊,那么,小编提问几个问题。
问题1:在封装callBack()函数的时候将callBack()函数的功能写死了吗?
问题2:callBack函数中的b()方法到底执行什么样的功能?
解答
问题1:callBack()函数的功能不能写死了,如果写死了,就失去了回调函数的意义了,因为callBack()自己也不知道到底执行什么功能,所以不能callBack()将这个函数的作用写“活”,置于callBack到底要实现什么功能?callBack自己都不知道,只有callBack的调用者才知道。
问题2:b()就是callBack调用者让callBack()函数做的具体事情。
到现在理解回调函数的功能了吧?就是因为回调函数自己都不知道自己究竟要干什么事情,所以回调函数将具体要完成的功能交给调用者来写,自己只是负责调用。回想一下Jquey的Ajax()的写法,以及$(“#id”).onClick(function(){}),还有jsonp的功能,这些都是回调啊!
小编在前言中说过,回调不仅在前台框架中使用,它是一种设计思想,是一种机制,在特定的需求场合下来解决某些问题。例如:在我们经常用的Spring中也有用到,下面小编就举个栗子!
Spring整合Hibernate
先来张图
- Spring在整合Hibernate的时候,将Hibernate的很多操作都封装在HibernateTemplate中,包括经常用session的一些操作,那么,如果我们想在Spring中操作Hibernate中一些原生的方法,那该怎么办?譬如说我要写一条多表的联合查询,条件也很复杂,像这样的功能HibernateTemplate并没有给我们封装,那怎么办?别着急,Hibernate给我们预留着接口了,这就是HibernateCallback的作用。下面来看个Demo。
public class ElecUserDaoImpl extends CommonDaoImpl<ElecUser> implements IElecUserDao {
public List<ElecUser> findCollectionByConditionNoPageWithSql(String condition,
final Object[] params, Map<String, String> orderby) {
//要执行的sql语句
String sql="select o.userID,o.logonName,o.userName,a.ddlName,o.contactTel,o.onDutyDate,b.ddlName " +
" from elec_user"+ " o inner join elec_systemddl a on o.sexID=a.ddlCode and a.keyword='性别'" +
" inner join elec_systemddl b on o.postID=b.ddlCode and b.keyword='职位'" +
" where 1=1";
//将Map集合中存放的字段排序,组织成ORDER BY o.textDate ASC,o.textName DESC
String orderbyCondition = this.orderbySql(orderby);
//添加查询条件
final String finalSql = sql + condition + orderbyCondition;
List<Object[]> list=this.getHibernateTemplate().execute(new HibernateCallback(){
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
Query query =session.createSQLQuery(finalSql)
.addScalar("o.userID")
.addScalar("o.logonName")
.addScalar("o.userName")
.addScalar("a.ddlName")
.addScalar("o.contactTel")
.addScalar("o.onDutyDate")
.addScalar("b.ddlName");
if(params!=null && params.length>0){
for(int i=0;i<params.length;i++){
query.setParameter(i, params[i]);
}
}
return query.list();
}});
//将List<Object[]>转换成List<ElecUser>
List<ElecUser> userList =new ArrayList<ElecUser>();
if (list!=null && list.size()>0) {
for (Object [] o : list) {
ElecUser elecUser = new ElecUser();
//o.userID,o.logonName,o.userName,a.ddlName,o.contactTel,o.onDutyDate,b.ddlName
elecUser.setUserID(o[0].toString());
elecUser.setLogonName(o[1].toString());
elecUser.setUserName(o[2].toString());
elecUser.setSexID(o[3].toString());
elecUser.setContactTel(o[4].toString());
elecUser.setOnDutyDate((Date)o[5]);
elecUser.setPostID(o[6].toString());
userList.add(elecUser);
}
}
return userList;
}
}
小结
- 看完这个Demo是不是感觉回调太牛X了,能解决很多问题,框架中的回调就是这么封装,这就是回调的魅力!