最近在做MISP的时候,很好奇Hibernate整合spring操作数据库的不同写法的区别,所以上网找了一些教程,认真研读并参考了其中几篇,写下(部分内容为copy,原谅我偷懒)了这篇学习笔记。
SessionFactory
用过Hibernate的同学都知道,在对数据库进行CRUD操作前,我们大概需要经历这样几个过程:
1、先得到SessionFactory,然后再openSession()或者getCurrentSession();
2、然后才是对数据库的操作;
3、操作结束之后,提交事务和closeSession(如果是通过getCurrentSession得到Session则不用关闭session);
当然,如果遇到异常,还需要回滚事务,抛出异常等。以下是我曾经的一段代码,用于保存一个Comment对象。
public void savaComment(Comment comment) { Session session = getSession();//getSession()通过SessionFactory获得session try { Transaction tx = session.beginTransaction(); // 开始事务 session.save(comment); tx.commit(); // 提交事务 } catch (RuntimeException e) { session.getTransaction().rollback(); // 回滚事务 throw e; } finally { session.close(); // 关闭Session } }
HibernateTemplate
从上面测试用的代码(省略了异常处理和事务回滚)来看,如果在业务层某部分的功能模块比较多,那我们不得不老实重复关于session的代码。为避免这样的窘境,于是有了HibernateTemplate的出现。
给HibernateTemplate注入SessionFactory,我们就能获得利用SessionFactory来create sessionFactory,进而进行所有关于sessionFactory的功能操作。同时,由于HibernateTemplate本身关于sessionFactory的处理原理,我们不再需要手动编写关于sessionFactory、session、transaction等等代码。我们只需要编写关于业务逻辑相关的操作,其他的一并由HibernateTemplate完成。HibernateTemplate的这种设计模式我们称之为TemplateMethod,采用的方式叫callback或者钩子函数。这里的重点就是把SessionFactory注入到HibernateTemplate里面!!!
Component("employeeDao") public class EmployeeDaoImpl implements EmployeeDao { private HibernateTemplate hibernateTemplate; public HibernateTemplate getHibernateTemplate() { return hibernateTemplate; } @Resource public void setHibernateTemplate(HibernateTemplate hibernateTemplate) { this.hibernateTemplate = hibernateTemplate; } @Override public void save(Employee employee) { hibernateTemplate().save(employee); }
上面的代码采用的是annotation方式,当然我们也可以使用xml方式,一样很简单。
HibernateDaoSupport
关于HibernateDaoSupport,spring通过 HibernateDaoSupport对SessionFactory底层进行了封装,控制session和事务变得简单。
在百度百科上的说法是,HibernateDaoSupport提供了基于AOP事务的自动处理,程序员完全可以不用理会事务的开始与提交。在继承HibrnateDaoSupport的DAO实现里,Hibernate Session的管理完全不需要Hibernate代码打开,而由Spring来管理。Spring会根据实际的操作,采用“每次事务打开一次session”的策略,自动提高数据库访问的性能。(大概意思就是你操作的时候,只要你的Dao类继承了HibernateDaoSupport,就可以不用再重复写【打开事务】【关闭事务】的代码了)
在继承HibernateDaoSupport的时候,需要给Dao类注入HibernateTemple或者SessionFactory(一两个Dao类还好,慢慢注入,但是Dao类多的话,每次都重复代码真的很烦人的),,所以一般都会创建一个顶层Dao类【BaseDao】,让BaseDao继承HibernateDaoSupport,并进行注入,其它的Dao类继承BaseDao,这样就省去很多功夫了。以下为一个例子:
import org.springframework.orm.hibernate3.HibernateTemplate; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; import org.springframework.stereotype.Component; @Component public class BaseDAO extends HibernateDaoSupport { @Resource(name="hibernateTemplate") public void setSuperHibernateTemplate(HibernateTemplate hibernateTemplate) { super.setHibernateTemplate(hibernateTemplate); } }
public class UserDAOImpl extends SuperDAO implements UserDAO { //Dao类实例 public void save(User user) { this.getHibernateTemplate().save(user); }
细心的童鞋可能发现了,上面的代码中导入的居然是Hibernate3!我用的是Hibernate4的囧,然后我找了以下Hibernate4的,居然找不到HibernateDaoSupport这个类了,乖乖地用第二种吧,网上推荐也是使用HibernateTemplate。
参考博客: http://javaeedevelop.iteye.com/blog/1483231 http://blog.csdn.net/yj_vs_gy/article/details/8604712
最后,推荐一个教程,可以创建通用的Dao层,不用每次都重复增删改查这些代码,感觉挺实用的 我的hibernate通用dao层 - 黑l①√Σ月 - 博客频道 - CSDN.NET 用Hibernate4的记得把获取Session的方式改一下。