首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

HibernateTemplate施用之手工管理Session和Transaction

2012-11-01 
HibernateTemplate使用之手工管理Session和Transaction大多数人在第一次使用HibernateTemplate时都很好奇,

HibernateTemplate使用之手工管理Session和Transaction
大多数人在第一次使用HibernateTemplate时都很好奇,不需要自己关闭Hibernate Session。如果在需要使用事务的情况一般使用spring配置TransactionProxyFactoryBean用AOP方式实现,还有就是使用HibernateTemplate的execute(HibernateCallback action)方法,构造一个匿名类实现HibernateCallback接口的Object doInHibernate(Session session)方法。使用前一种方法需要使用spring IOC,后一种代码因为使用匿名类,如果有较多逻辑代码显得难看、不清晰。是否还有其他使用HibernateTemplate的简单方法呢。
查看HibernateTemplate源码发现,如果不存在事务,每次执行HibernateTemplate方法都会取得新Session,执行完数据库操作后再关闭Session。虽说不是每次都是真正开关数据库连接,但总感觉这样做不好。我们需要即使多次执行HibernateTemplate中方法是用的同一个Session,这样既不浪费资源,也可以自己手工管理事务。现在就来写一个工具类模拟OpenSessionInView模式和HibernateTransactionManager功能

import org.hibernate.FlushMode;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.springframework.orm.hibernate3.HibernateTemplate;import org.springframework.orm.hibernate3.SessionFactoryUtils;import org.springframework.orm.hibernate3.SessionHolder;import org.springframework.transaction.support.TransactionSynchronizationManager;import org.springframework.util.Assert;public class HibernateSessionUtils{private static final ThreadLocal sessionFactoryLocal = new ThreadLocal();public static void getSession(SessionFactory sessionFactory){getSession(sessionFactory,null);}public static void getSession(SessionFactory sessionFactory,FlushMode flushMode){if (TransactionSynchronizationManager.hasResource(sessionFactory))return;Session session = SessionFactoryUtils.getSession(sessionFactory, true);if (flushMode != null) {session.setFlushMode(flushMode);}TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));sessionFactoryLocal.set(sessionFactory);}public static void beginTransaction(){SessionFactory sessionFactory = (SessionFactory) sessionFactoryLocal.get();Assert.state(sessionFactory != null,"No existing sessionFactory found for thread");SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.getResource(sessionFactory);Assert.state(sessionHolder != null,"No existing session found for transaction");Transaction transaction = sessionHolder.getTransaction();Assert.state(transaction == null,"transaction already found for transaction");transaction = sessionHolder.getSession().beginTransaction();transaction.begin();sessionHolder.setTransaction(transaction);}public static void commit(){commit(true);}public static void commit(boolean autoClose){SessionFactory sessionFactory = (SessionFactory) sessionFactoryLocal.get();Assert.state(sessionFactory != null,"No existing sessionFactory found for thread");    SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.getResource(sessionFactory);Assert.state(sessionHolder != null,"No existing session found for transaction");Transaction transaction = sessionHolder.getTransaction();Assert.state(transaction != null,"No transaction found for transaction");transaction.commit();sessionHolder.setTransaction(null);if(autoClose)closeSession();}public static void rollback(){SessionFactory sessionFactory = (SessionFactory) sessionFactoryLocal.get();Assert.state(sessionFactory != null,"No existing sessionFactory found for thread");SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.getResource(sessionFactory);Assert.state(sessionHolder != null,"No existing session found for transaction");Transaction transaction = sessionHolder.getTransaction();Assert.state(transaction != null,"No transaction found for transaction");transaction.rollback();sessionHolder.setTransaction(null);}public static void closeSession(){SessionFactory sessionFactory = (SessionFactory) sessionFactoryLocal.get();if(sessionFactory == null)return;SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);if(sessionHolder != null){Transaction transaction = sessionHolder.getTransaction();Assert.state(transaction == null,"Transaction found for session");}SessionFactoryUtils.closeSession(sessionHolder.getSession());sessionFactoryLocal.set(null);}}


使用示例
public static void main(String[] args) {SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();HibernateTemplate template = new HibernateTemplate(sessionFactory);HibernateSessionUtils.getSession(sessionFactory);//do any thingtemplate.find("....");HibernateSessionUtils.beginTransaction();template.save(null);HibernateSessionUtils.commit();HibernateSessionUtils.closeSession();}

编写测试代码或少量代码可以采用这种方式,如果是真正应用的话还是使用Spring IOC和AOP比较好,不推荐这种手工方式 1 楼 taupo 2008-06-05   我们需要即使多次执行HibernateTemplate中方法是用的同一个Session,这样既不浪费资源,也可以自己手工管理事务

这个想法我觉得很好,但是一般都有事务的存在,所以我觉得楼主的这个实用性不高,呵呵 2 楼 left405 2009-02-20   好东西, 收藏了.

热点排行