在分析HibernateTemplate前,首先从网上了解下一些关于回调的一些概念。我相信在了解其原理实现的基础上,可以更好的进行开发和扩展,关键得理解其思想。
软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。
同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用。(简单来说就是顺序执行啦。)
回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口。(个人觉得有点像模板方法的实现。)
异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。(差不多就是异步执行吧。)
回调和异步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。同步调用是三者当中最简单的,而回调又常常是异步调用的基础。
由于本文章主要关注的是Java 的回调机制,所以其他就不介绍了。下面来看看Java 是怎么来实现回调机制的。
-
packagecallback;
-
-
-
-
-
-
-
publicclassTest{
-
privateCallbackcallback;
-
publicvoidsetCallback(Callbackcallback){
-
this.callback=callback;
-
}
-
-
publicvoidfoo(){
-
System.out.println("thisisfoo();");
-
-
if(callback!=null){
-
callback.doSomething();
-
}
-
}
-
-
publicstaticvoidmain(String[]args){
-
Testt=newTest();
-
t.setCallback(newCallback(){
-
publicvoiddoSomething(){
-
System.out.println("thisiscallback.");
-
}
-
});
-
-
t.foo();
-
}
-
-
}
-
-
interfaceCallback{
-
voiddoSomething();
-
}
一般在我们数据库开发中,都会有打开和关闭数据、捕获异常等的一些固定的操作,写久了也就特别的反感了。是吧。。下面来利用回调简化数据库操作,例子很简单,对于数据的打开和关闭我只做了简单的描述。
-
packagecallback;
-
-
publicclassUserDao{
-
privateUserTemplatetemplate=newUserTemplate();
-
-
-
publicvoidadd(finalStringname){
-
this.template.add(name);
-
}
-
-
publicStringgetName(){
-
return(String)this.template.execute(newUserCallback(){
-
publicObjectdoSomething(){
-
System.out.println("成功读取数据库。。。name=zhxing");
-
return"zhxing";
-
}
-
});
-
}
-
-
-
publicstaticvoidmain(String[]args){
-
UserDaou=newUserDao();
-
u.add("zhxing");
-
System.out.println(u.getName());
-
}
-
}
-
-
packagecallback;
-
-
publicclassUserTemplate{
-
-
publicObjectexecute(UserCallbackcallback){
-
System.out.println("打开数据库连接");
-
Objecto=callback.doSomething();
-
System.out.println("关闭数据库连接");
-
returno;
-
}
-
-
-
publicvoidadd(finalStringname){
-
execute(newUserCallback(){
-
publicObjectdoSomething(){
-
System.out.println("name="+name+"成功加入数据库。。。");
-
returnnull;
-
}
-
});
-
}
-
-
}
-
-
packagecallback;
-
-
publicinterfaceUserCallback{
-
ObjectdoSomething();
-
}
好了,进入正题吧。。来研究下Spring 中HibernateTemplate 是怎么实现了。。其实上面的那个例子已经可以说明全部了,呵呵。。下面我们按照开发的流程来进行一些源码分析。
当我们用Spring+Hibernate实现Dao层的时候,一般会去继承HibernateDaoSupport这个类。
来分析下这个HibernateDaoSupport类(具体方法细节请查看源码):
-
publicabstractclassHibernateDaoSupportextendsDaoSupport{
-
-
privateHibernateTemplatehibernateTemplate;
-
-
publicfinalvoidsetSessionFactory(SessionFactorysessionFactory){
-
}
-
protectedHibernateTemplatecreateHibernateTemplate(SessionFactorysessionFactory){
-
}
-
-
publicfinalSessionFactorygetSessionFactory(){
-
-
}
-
-
publicfinalvoidsetHibernateTemplate(HibernateTemplatehibernateTemplate){
-
this.hibernateTemplate=hibernateTemplate;
-
}
-
publicfinalHibernateTemplategetHibernateTemplate(){
-
returnthis.hibernateTemplate;
-
}
-
-
protectedfinalvoidcheckDaoConfig(){
-
if(this.hibernateTemplate==null){
-
thrownewIllegalArgumentException("'sessionFactory'or'hibernateTemplate'isrequired");
-
}
-
}
-
-
-
-
protectedfinalSessiongetSession()
-
throwsDataAccessResourceFailureException,IllegalStateException{
-
-
returngetSession(this.hibernateTemplate.isAllowCreate());
-
}
-
-
-
protectedfinalSessiongetSession(booleanallowCreate)
-
throwsDataAccessResourceFailureException,IllegalStateException{
-
-
return(!allowCreate?
-
SessionFactoryUtils.getSession(getSessionFactory(),false):
-
SessionFactoryUtils.getSession(
-
getSessionFactory(),
-
this.hibernateTemplate.getEntityInterceptor(),
-
this.hibernateTemplate.getJdbcExceptionTranslator()));
-
}
-
-
-
protectedfinalDataAccessExceptionconvertHibernateAccessException(HibernateExceptionex){
-
returnthis.hibernateTemplate.convertHibernateAccessException(ex);
-
}
-
-
-
protectedfinalvoidreleaseSession(Sessionsession){
-
SessionFactoryUtils.releaseSession(session,getSessionFactory());
-
}
-
-
}
从上面可知道,HibernateDaoSupport 的主要作用是获取Hibernate 的Session (如果直接用HibernateTemplate是没有办法获得Session 的)和管理HibernateTemplate。在Spring 中可以对直接继承该类,然后在Dao 的配置上就可以直接进行注入SessionFactory了,还可以直接从Dao中获取Hibernate的Session进行操作。
现在回到正题,进行分析下HibernateTemplate,先看下他的成员变量有哪些。
-
publicclassHibernateTemplateextendsHibernateAccessorimplementsHibernateOperations{
-
-
privatebooleanallowCreate=true;
-
-
privatebooleanalwaysUseNewSession=false;
-
-
privatebooleanexposeNativeSession=false;
-
-
privatebooleancheckWriteOperations=true;
-
-
privatebooleancacheQueries=false;
-
-
privateStringqueryCacheRegion;
-
-
privateintfetchSize=0;
-
-
privateintmaxResults=0;
-
}
HibernateTemplate 封装了很多Hibernate 的原始的操作,但把Hibernate 的session设置为了protected,而不能在它的子类外进行获取。下面来看看我们最常用get 和save 方法。
-
publicObjectget(ClassentityClass,Serializableid)throwsDataAccessException{
-
returnget(entityClass,id,null);
-
}
-
-
publicObjectget(finalClassentityClass,finalSerializableid,finalLockModelockMode)
-
throwsDataAccessException{
-
-
returnexecuteWithNativeSession(newHibernateCallback(){
-
publicObjectdoInHibernate(Sessionsession)throwsHibernateException{
-
if(lockMode!=null){
-
returnsession.get(entityClass,id,lockMode);
-
}
-
else{
-
returnsession.get(entityClass,id);
-
}
-
}
-
});
-
}
-
-
publicSerializablesave(finalObjectentity)throwsDataAccessException{
-
-
return(Serializable)executeWithNativeSession(newHibernateCallback(){
-
publicObjectdoInHibernate(Sessionsession)throwsHibernateException{
-
checkWriteOperationAllowed(session);
-
returnsession.save(entity);
-
}
-
});
-
}
下面来看看这个回调函数的方法。
-
protectedObjectdoExecute(HibernateCallbackaction,booleanenforceNewSession,booleanenforceNativeSession)
-
throwsDataAccessException{
-
-
Assert.notNull(action,"Callbackobjectmustnotbenull");
-
-
Sessionsession=(enforceNewSession?
-
SessionFactoryUtils.getNewSession(getSessionFactory(),getEntityInterceptor()):getSession());
-
-
booleanexistingTransaction=(!enforceNewSession&&
-
(!isAllowCreate()||SessionFactoryUtils.isSessionTransactional(session,getSessionFactory())));
-
if(existingTransaction){
-
logger.debug("Foundthread-boundSessionforHibernateTemplate");
-
}
-
-
FlushModepreviousFlushMode=null;
-
try{
-
-
previousFlushMode=applyFlushMode(session,existingTransaction);
-
-
enableFilters(session);
-
-
SessionsessionToExpose=
-
(enforceNativeSession||isExposeNativeSession()?session:createSessionProxy(session));
-
-
Objectresult=action.doInHibernate(sessionToExpose);
-
flushIfNecessary(session,existingTransaction);
-
returnresult;
-
}
-
catch(HibernateExceptionex){
-
throwconvertHibernateAccessException(ex);
-
}
-
catch(SQLExceptionex){
-
throwconvertJdbcAccessException(ex);
-
}
-
catch(RuntimeExceptionex){
-
-
throwex;
-
}
-
finally{
-
if(existingTransaction){
-
logger.debug("Notclosingpre-boundHibernateSessionafterHibernateTemplate");
-
disableFilters(session);
-
if(previousFlushMode!=null){
-
session.setFlushMode(previousFlushMode);
-
}
-
}
-
else{
-
-
if(isAlwaysUseNewSession()){
-
SessionFactoryUtils.closeSession(session);
-
}
-
else{
-
-
}
-
}
-
}
-
}
到这里基本就简单分析完了,关于HibernateTemplate的其他操作,其实都差不多的,对Hibernate的一些常用操作进行了回调封装,可以自己分析下。
分享到:
相关推荐
Spring整合hibernate(2)之基于HibernateTemplate的整合,jar需要自己添加!
Spring和Hibernate源码下载 Spring_Spring_Hibernate_HibernateTemplate
spring hibernatetemplate
spring HibernateTemplate汇总
Spring_2000_Spring_Hibernate_HibernateTemplate,Spring_2000_Spring_Hibernate_HibernateTemplate
Spring+hibernate整合源代码 结束Sping+hibernate 的使用方法 包括演示示例
对Spring框架中,HibernateTemplate的使用,底层dao中HibernateTemplate的使用以及HibernateCallBack调用等等
6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.1.1. @Configurable object的单元测试 6.8.1.2. 多application context情况下的处理 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来...
hibernateTemplate的常用方法
6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...
HibernateTemplate的简单示例
HibernateTemplate的用法总结,我自己整理的,仅供参考
HibernateTemplate 的常规用法.doc HibernateTemplate 的常规用法.doc
关于使用HibernateTemplate
HibernateTemplate的方法部分使用,还有部分的个人见解,有错的,请指出,谢谢
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 数据库事务基础...
NULL 博文链接:https://tedtian.iteye.com/blog/1988917
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. 在应用...
HibernateTemplat技术,此文档详细描述了HibernateTemplate的方法及功能说明,并有实例。