`
java虫
  • 浏览: 537796 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

结合HibernateTemplate学习回调模式

阅读更多
学习了spring的HibernateTemplate类部分源码,总结一下自己对回调模式的理解。

在dao里经常有这样的语句
public E findById(Serializable id)
{
return (E) getHibernateTemplate().get(clazz, id);
}

HibernateTemplate类源码

public Object get(Class entityClass, Serializable id) throws DataAccessException {
		return get(entityClass, id, null);
	}

public Object get(final Class entityClass, final Serializable id, final LockMode lockMode)
			throws DataAccessException {

		return execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException {
				if (lockMode != null) {	
					return session.get(entityClass, id, lockMode);
				}
				else {
					return session.get(entityClass, id);
				}
			}
		}, true);
	}

public Object execute(HibernateCallback action) throws DataAccessException {
		return execute(action, isExposeNativeSession());
	}

public Object execute(HibernateCallback action, boolean exposeNativeSession) throws DataAccessException {
		Assert.notNull(action, "Callback object must not be null");

		Session session = getSession();
		boolean existingTransaction = SessionFactoryUtils.isSessionTransactional(session, getSessionFactory());
		if (existingTransaction) {
			logger.debug("Found thread-bound Session for HibernateTemplate");
		}

		FlushMode previousFlushMode = null;
		try {
			previousFlushMode = applyFlushMode(session, existingTransaction);
			enableFilters(session);
			Session sessionToExpose = (exposeNativeSession ? session : createSessionProxy(session));
			Object result = action.doInHibernate(sessionToExpose);			flushIfNecessary(session, existingTransaction);
			return result;
		}
		catch (HibernateException ex) {
			throw convertHibernateAccessException(ex);
		}
		catch (SQLException ex) {
			throw convertJdbcAccessException(ex);
		}
		catch (RuntimeException ex) {
			// Callback code threw application exception...
			throw ex;
		}
		finally {
			if (existingTransaction) {
				logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");
				disableFilters(session);
				if (previousFlushMode != null) {
					session.setFlushMode(previousFlushMode);
				}
			}
			else {
				// Never use deferred close for an explicitly new Session.
				if (isAlwaysUseNewSession()) {
					SessionFactoryUtils.closeSession(session);
				}
				else {
					SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory());
				}
			}
		}
	}


HibernateTemplate类是对hibernate操作的封装。如果要自己写hibernate的操作,最麻烦的是那些要检查的错误,而且每一个地方都一样。不一样的地方只是真正对数据库操作的语句。spring的想法是一样的代码抽取出来写成一个HibernateTemplate中的execute方法。execute的方法参数是HibernateCallback接口类。HibernateCallback里面定义了一个doInHibernate的方法。因为这个方法是变的。比如你是查找数据方法应该就是:session.load()。删除数据就是session.delete().这样的话查询数据库的方法用execute方法。

HibernateCallback 接口类
public interface HibernateCallback {

	Object doInHibernate(Session session) throws HibernateException, SQLException;
}

然后使用内部类的形式把HibernateCallback中的方法doInHibernate实例化。
new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException {
				if (lockMode != null) {	
					return session.get(entityClass, id, lockMode);
				}
				else {
					return session.get(entityClass, id);
				}
			}

总的想法就是不变的东西可以抽象出一个方法。比如对异常的检查。变的东西,比如对数据库的操作,抽象出一个接口的方法。

总结
JAVA的CALLBACK通过接口来实现。  
  例:  
  1.HibernateTemplate,内联类 
  2.内联类实现接口HibernateCallback的doInHibernate 方法
  3.HibernateTemplate拥有一个参数为HibernateCallback接口类型的函数execute(HibernateCallback action)方法.
  4.调用HibernateTemplate的get方法时,将内联类传给了excute方法  
  5.执行excute方法时,(你调用它)
已取得内联类,就可以随时回调它所实现的HibernateCallback接口中的方法了,
这时它反过来调用你的方法(它调用你),这就是回调了.


Javaeye两个会员的理解,我觉得比较到位.
冉翔:

就是调用系统的一个方法,传进去一个接口的实现类 or 匿名类。
然后系统的方法调用接口申明的方法,并且注入相应的参数


Buaawhl
:
IoC, Functor, Visitor 都是 callback。
就是一个 Template Methond 里面的flow不变,某一个步骤的具体操作变化,这个变化部分需要从外部(参数,或者属性,或者 override parent method)注入。
类似于从前的 C 回调函数指针。
MainFlow ( callback ){
step1; 
.... 

callback( someThing );
.... 
stepN;
} 

  


  
分享到:
评论
1 楼 GFreedom 2007-08-29  
学习ing

相关推荐

    ssh框架整合分页--内部类回调函数

    模型-视图-控制器)架构以及Hibernate的持久化技术完美地结合在一起,为开发者提供了一种高效、灵活的开发模式。在实际项目中,我们经常需要处理大量的数据,此时分页功能显得尤为重要。 分页功能在SSH框架中实现...

    HibernateS整合pring

    此外,`HibernateTemplate`还支持`HibernateCallback`接口,允许开发者在回调方法`doInHibernate(Session session)`中使用原生的Hibernate API,以应对更复杂的数据访问需求。这种方法确保了灵活性,即使在Spring的...

    mysql-jdbc-Spring源代码分析

    3. **执行回调逻辑**:调用传入的`ConnectionCallback`对象的`doInConnection`方法,执行用户自定义的数据库操作逻辑。 4. **异常处理**:如果执行过程中发生`SQLException`,则会通过`DataSourceUtils....

    SSH整合文档

    3. **使用HibernateCallback**: HibernateCallback是一个接口,可以在Session中执行回调方法,例如查询数据。 ```java HibernateCallback<List<Dept>> callback = new HibernateCallback<List<Dept>>() { @...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    2、 Ajax我们主要应用就是xmlhttprequest,回调函数实现局部刷新达道数据更新! 4.2需求分析 Blog网站主要是实现注册用户登录、管理相关信息、博文及相关评论、查看留言、友情链接、及图片的上传和图像的播放而为...

    Spring中文帮助文档

    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. 在应用...

    Spring API

    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. 在应用...

Global site tag (gtag.js) - Google Analytics