当前位置:首页 > 开发 > 编程语言 > Hibernate > 正文

HibernateTemplate 理解(对Callback继续理解)

发表于: 2013-10-30   作者:abc08010051   来源:转载   浏览:
摘要:     经常使用spring封装hibernate的同学,在写dao的具体实现类的时候,一般都会让dao实现类继承HibernateDaoSupport, 这样,在我们的dao实现类中就可以直接获得HibernateTemplate对象来直接使用,HibernateTemplate封装Hibernate的基本操作,    通过Hibernate

    经常使用spring封装hibernate的同学,在写dao的具体实现类的时候,一般都会让dao实现类继承HibernateDaoSupport,

这样,在我们的dao实现类中就可以直接获得HibernateTemplate对象来直接使用,HibernateTemplate封装Hibernate的基本操作,

   通过HibernateTemplate源码可知,我们需要给hibernateTemplate一个sessionFactory;一般都是通过spring注入

   hibernateTemplate提供了一系列的CRUD方法,现在我们以get的实现来说明:

  

//我们实际调用的方法	
public <T> T get(Class<T> entityClass, Serializable id) throws DataAccessException {
		return get(entityClass, id, null);
	}
//真实实现
	public <T> T get(final Class<T> entityClass, final Serializable id, final LockMode lockMode)
			throws DataAccessException {

		return executeWithNativeSession(new HibernateCallback<T>() {
			@SuppressWarnings("unchecked")
			public T doInHibernate(Session session) throws HibernateException {
				if (lockMode != null) {
					return (T) session.get(entityClass, id, lockMode);
				}
				else {
					return (T) session.get(entityClass, id);
				}
			}
		});
	}

//被调用方法
	public <T> T executeWithNativeSession(HibernateCallback<T> action) {
		return doExecute(action, false, true);
	}

    get()方法的具体实现是doExecute()方法,在此使用的Callback,把相同的操作都封装到了doExecute()方法中,具体的实现就在get()方法中HibernateCallback中实现,通过上面的代码可以看出,我们的Callback方法doInHibernate需要一个参数session, 此参数是在doExecute方法中传入的(doExecute方法在下面描述),真正的获取值最终还是去操作session,这里就和Hibernate里操作一样,只不过此时的session的管理和事务的管理都在

doExecute()方法中来完成,我们不需要关心,我们只需要关心我们的Callback实现我们需要的逻辑。

 

  下面我们看一下delete方法的实现:

 

//我们调用的方法	
public void delete(Object entity) throws DataAccessException {
		delete(entity, null);
	}

//具体实现方法
	public void delete(final Object entity, final LockMode lockMode) throws DataAccessException {
		executeWithNativeSession(new HibernateCallback<Object>() {
			public Object doInHibernate(Session session) throws HibernateException {
				checkWriteOperationAllowed(session);
				if (lockMode != null) {
					session.lock(entity, lockMode);
				}
				session.delete(entity);
				return null;
			}
		});
	}

   看到吗?和get方法如出一辙,底层实现使用doExecute方法,具体实现放到自己的Callback里

 

   再看一下复杂操作时,我们会调用execute方法,execute方法的实现:

  

public <T> T execute(HibernateCallback<T> action) throws DataAccessException {
		return doExecute(action, false, false);
	}

   对,不会错了把,HibernateTemplate就是使用Callback模式把所有的方法的相同实现都放到了doExecute()方法中,具体实现放到CallBack中,Callback的抽象方法需要session,得到session后和hibernate的操作一抹一样。

 

  下面我们就来看看doExecute()方法的具体实现:

  

	protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNewSession, boolean enforceNativeSession)
			throws DataAccessException {

		Assert.notNull(action, "Callback object must not be null");

		Session session = (enforceNewSession ?
				SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor()) : getSession());
		boolean existingTransaction = (!enforceNewSession &&
				(!isAllowCreate() || 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 =
					(enforceNativeSession || isExposeNativeSession() ? session : createSessionProxy(session));
                        //此操作以前的代码都是在管理session,处理事务
			T result = action.doInHibernate(sessionToExpose);//此行调用了HibernateCallback的具体逻辑
			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());
				}
			}
		}
	}

    代码逻辑很清晰,前半部分去获取session,管理事务,然后就是调用hibernateCallback中具体实现的逻辑,返回结果,然后做具体的事务和session管理,

 

   针对于hibernateTemplate提供的其他方法也是一样,使用callback模式,相同的操作都放到了doExecute中

 

   就这样hibernateTemplate屏蔽了hibernate的复杂操作,实现了封装

 

HibernateTemplate 理解(对Callback继续理解)

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
inode是一个重要概念,是理解Unix/Linux文件系统和硬盘储存的基础。 我觉得,理解inode,不仅有助于
原文链接:理解ThreadLocal ThreadLocal是一个线程级别的局部变量,并非“本地线程”。ThreadLocal
在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之
http://www.cescg.org/CESCG-2002/GSchroecker/node14.html http://www.eng.utah.edu/~cs5610/lectu
背景 前段时间一个项目中因为涉及大量的线程开发,把jdk cocurrent的代码重新再过了一遍。这篇文章
什么是 chroot chroot,即 change root directory (更改 root 目录)。在 linux 系统中,系统默认的
从inode的角度理解软链接和硬链接的区别。转载自:http://www.ruanyifeng.com/blog/2011/12/inode.h
概述 我们知道Spring通过各种DAO模板类降低了开发者使用各种数据持久技术的难度。这些模板类都是线
ThreadLocal是什么 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序
MapReduce的理解 1 什么是MapReduce?   Map本意可以理解为地图,映射(面向对象语言都有Map集合
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号