大多数人在第一次使用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 thing
template.find("....");
HibernateSessionUtils.beginTransaction();
template.save(null);
HibernateSessionUtils.commit();
HibernateSessionUtils.closeSession();
}
编写测试代码或少量代码可以采用这种方式,如果是真正应用的话还是使用Spring IOC和AOP比较好,不推荐这种手工方式
分享到:
相关推荐
关于使用HibernateTemplate
对Spring框架中,HibernateTemplate的使用,底层dao中HibernateTemplate的使用以及HibernateCallBack调用等等
HibernateTemplate的方法部分使用,还有部分的个人见解,有错的,请指出,谢谢
HibernateTemplate 的常规用法.doc HibernateTemplate 的常规用法.doc
spring HibernateTemplate汇总
hibernateTemplate的常用方法
HibernateTemplate类的使用
HibernateTemplate的简单示例
HibernateTemplate的用法总结,我自己整理的,仅供参考
Spring整合hibernate(2)之基于HibernateTemplate的整合,jar需要自己添加!
hibernateTemplate常用方法.htm
HibernateTemplat技术,此文档详细描述了HibernateTemplate的方法及功能说明,并有实例。
HibernateTemplate源代码
JavaWeb开发,Sping框架,才用Hibernate Template进行字段截取,分组统计实现方法。
GenericHibernateDao 继承 HibernateDao,简单封装 HibernateTemplate 各项功能,简化基于Hibernate Dao 的编写。
hibernateTemplate和HibernateDaoSupport
hibernateDaoSurpport和hibernateTemplate
SSH2增删改查使用HibernateTemplate
基于HIbernateTemplate的代码自动生成,能够自动生成dao和service文件,提高开发效率