在接触HibernateTemplate之前,我们知道,在对数据库进行CRUD操作之前,需要开启session、transaction等等。在hibernate学习过程中,我们知道了,得到session之前,需要先得到SessionFactory,进而从SessionFactory里面openSession(),或者getCurrentSession(),接着开启一transaction,然后进行对数据库的操作,在操作结束后,提交事务,关闭session。当然如果session是通过getCurrentSession()得到的话,不用我们手动关闭。还有,关于异常的处理,这就涉及到事务的回滚。我们发现,这样逻辑的代码我们需要反复使用,每次session的历程都是这样的。实例代码如下:

  1. public class HibernateCoreAPITest {
  2. private static SessionFactory sessionFactory;
  3. @BeforeClass
  4. public static void beforeClass() {
  5. sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
  6. }
  7. @AfterClass
  8. public static void afterClass() {
  9. sessionFactory.close();
  10. }
  11. @Test
  12. public void testTeacherSave() {
  13. Teacher t = new Teacher();
  14. t.setName("t1");
  15. t.setTitle("middle");
  16. t.setBirthDate(new Date());
  17. //Session session = sessionFactory.openSession();
  18. Session session = sessionFactory.getCurrentSession();
  19. session.beginTransaction();
  20. session.save(t);
  21. session.getTransaction().commit();
  22. }

HibernateTemplate

从上面测试用的代码(省略了异常处理和事务回滚)来看,如果在业务层某部分的功能模块比较多,那我们不得不老实重复关于session的代码。为避免这样的窘境,于是有了HibernateTemplate的出现。

给HibernateTemplate注入SessionFactory,我们就能获得利用SessionFactory来create sessionFactory,进而进行所有关于sessionFactory的功能操作。同时,由于HibernateTemplate本身关于sessionFactory的处理原理,我们不再需要手动编写关于sessionFactory、session、transaction等等代码。我们只需要编写关于业务逻辑相关的操作,其他的一并由HibernateTemplate完成。HibernateTemplate的这种设计模式我们称之为TemplateMethod,采用的方式叫callback或者钩子函数。这里的重点就是把SessionFactory注入到HibernateTemplate里面!!!

  1. <span style="font-size:18px;">@Component("employeeDao")
  2. public class EmployeeDaoImpl implements EmployeeDao {
  3. private HibernateTemplate hibernateTemplate;
  4. public HibernateTemplate getHibernateTemplate() {
  5. return hibernateTemplate;
  6. }
  7. @Resource
  8. public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
  9. this.hibernateTemplate = hibernateTemplate;
  10. }
  11. @Override
  12. public void save(Employee employee) {
  13. hibernateTemplate().save(employee);
  14. }</span>

上面的代码采用的是annotation方式,当然我们也可以使用xml方式,一样很简单。

HibernateDaoSupport

HibernateDaoSupport对于HibernateTemplate,就好比HibernateTemplate对于SessionFactory,两两的关系,大致雷同。只是这一次,HibernateDaoSupport是需要被继承的,而且不能像后者那样减少什么的代码量。就是把HibernateTemplate注入到HibernateDaoSupport里面,当然把SessionFactory注入到HibernateDaoTemplate里面一样可以。而起由于在HibernateDaoSupport里面set方法是final类型的,我们不能够重写该方法,所以就不能过通过annotation方式注入HibernateTemplate,只有采用xml方式。

  1. <span style="font-size:18px;"><bean id="employeeDao" class="com.zzw.dao.impl.EmployeeDaoImpl">
  2. <property name="hibernateTemplate" ref="hibernateTemplate"></property>
  3. </bean></span>
  1. <span style="font-size:18px;">public class EmployeeDaoImpl extends HibernateDaoSupport implements EmployeeDao {
  2. @Override
  3. public void save(Employee employee) {
  4. this.getHibernateTemplate().save(employee);
  5. }
  6. @Override
  7. public void delete(Employee employee) {
  8. this.getHibernateTemplate().delete(employee);
  9. }
  10. @Override
  11. public void update(Employee employee) {
  12. this.getHibernateTemplate().update(employee);
  13. }</span>

接着,我们来谈谈HibernateDaoSupport的拓展,当多个***Dao需要注入继承HibernateDaoSupport的时候,理所当然,我们得在applicationContext.xml里面给每个Dao注入hibernateTemplate或者sessionFactory。少量的好说,但是如果很多,比如几百个Dao(当然,这种情况我们很少遇到,我们假设这样),这样,由于采用的是xml方式,我们配置起来一样显得麻烦。这个时候,我们可以这样解决,抽象一个顶层Dao类,这个类必须注入HibernateTemplate,其实这个注入了HibernateTemplate的顶层Dao类,他的功能类似于HibernateDaoSupport类,唯一的不同就是这个类里面的set方法是我们自己定义的,不是final类型的,所以我们采用注解annotation方式注入HibernateTemplate。然后,让那些***Dao继承这个顶层Dao类。这样在xml里面不用编写任何的注解配置,当然除了在HibernateTemplate里面注入sessionFactory。

注入HibernateTemplate的顶层Dao类:SuperDao.java

  1. <span style="font-size:18px;">import javax.annotation.Resource;
  2. import org.springframework.orm.hibernate3.HibernateTemplate;
  3. import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
  4. import org.springframework.stereotype.Component;
  5. @Component
  6. public class SuperDAO {
  7. private HibernateTemplate hibernateTemplate;
  8. public HibernateTemplate getHibernateTemplate() {
  9. return hibernateTemplate;
  10. }
  11. @Resource
  12. public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
  13. this.hibernateTemplate = hibernateTemplate;
  14. }
  15. }</span>

众多***Dao里面的一实例:UserDao.java

  1. <span style="font-size:18px;">@Component("userDAO")
  2. public class UserDAOImpl extends SuperDAO implements UserDAO {
  3. public void save(User user) {
  4. this.getHibernateTemplate().save(user);
  5. }
  6. }</span>

从上面的代码中,我们发现整个过程我们并没有使用HibernateDaoSupport这个抽象类,而是使用一个它的替代类:由我们自己定义的。如果非得使用HibernateDaoSupport类的话,也可以,就是讲顶层Dao类SuperDao改为:

  1. <span style="font-size:18px;">@Component
  2. public class SuperDAO extends HibernateDaoSupport {
  3. @Resource(name="hibernateTemplate")
  4. public void setSuperHibernateTemplate(HibernateTemplate hibernateTemplate) {
  5. super.setHibernateTemplate(hibernateTemplate);
  6. }
  7. }
  8. </span>

注意:spring容器在对子类进行初始化的时候,首先会将其父类进行初始化,而如果两者的注入方式不一致,比如一个是xml方式,一个是annotation方式的话,很容易出错,所以,最好使用同种注入方式!

最后,温馨提示:建议使用HibernateTemplate的annotation注入方式,即第二种哦,亲!

SessionFactory、HibernateTemplate、HibernateDaoSupport之间的关系说明的更多相关文章

  1. 通俗易懂理清mybatis中SqlSessionSql、SqlSessionTemplate、SessionFactory和SqlSessionFactoryBean之间的关系

    我潇洒的灰大狼又回来啦.今天送大家的一句话是: 保持耐心,永远年轻,永远热泪盈眶. 前言 先容我哭一会儿,呜呜呜~昨晚写了一半的文章,还没保存就盖上盖子准备回家,拔下电源准备把电脑塞进书包带回家完成时 ...

  2. JPA概述以及它和Hibernate之间的关系

    http://www.cnblogs.com/Kevin-ZhangCG/p/8996491.html 一.JPA概述以及它和Hibernate之间的关系 1.1.Hibernate 概述 JPA J ...

  3. 五、hibernate表与表之间的关系(一对多关系)

    数据库表与表之间的关系 一对多:一个学校可以有多个学生,一个学生只能有一个学校 多对多:一个学生可以有多个老师,一个老师可以教多个学生 一对一:一个人只能有一个身份证号,一个身份证号只能找到一个人 一 ...

  4. .NET Core与.NET Framework、Mono之间的关系

    随着微软的.NET开源的推进,现在在.NET的实现上有了三个.NET Framework,Mono和.NET Core.经常被问起Mono的稳定性怎么样,后续Mono的前景如何,要回答这个问题就需要搞 ...

  5. .NET Core 和 .NET Framework 之间的关系

    引用一段描述:Understanding the relationship between .NET Core and the .NET Framework. .NET Core and the .N ...

  6. 实体之间的关系【Entity Relationships】(EF基础系列篇9)

    Here, you will learn how entity framework manages the relationships between entities. Entity framewo ...

  7. php CGI、Fastcgi、PHP-FPM的详细介绍与之间的关系

    以下PHP CGI.Fastcgi.PHP-FPM的一些信息归纳和汇总----->详细介绍与之间的关系 一:CGI是干嘛的?CGI是为了保证web server传递过来的数据是标准格式的 web ...

  8. [转] valuestack,stackContext,ActionContext.之间的关系

    三者之间的关系如下图所示: ActionContext  一次Action调用都会创建一个ActionContext  调用:ActionContext context = ActionContext ...

  9. angular源码阅读,依赖注入的原理:injector,provider,module之间的关系。

    最开始使用angular的时候,总是觉得它的依赖注入方式非常神奇. 如果你跳槽的时候对新公司说,我曾经使用过angular,那他们肯定会问你angular的依赖注入原理是什么? 这篇博客其实是angu ...

随机推荐

  1. Vagrant工具

    Vagrant 是一款用来构建虚拟开发环境的工具,非常适合 php/python/ruby/java 这类语言开发 web 应用,“代码在我机子上运行没有问题”这种说辞将成为历史. 我们可以通过 Va ...

  2. Java知识点:内部类

    内部类class文件命名规则 普通内部类.静态内部类:<Outer>\$<Inner>.class,其中<Outer>为外部类类名,<Inner>为内部 ...

  3. HDU 2544 最短路 (最短路,spfa)

    题意:中文题目 思路:spfa+SLF优化.关于SPFA的详情请戳我 #include <bits/stdc++.h> using namespace std; , INF=0x7f7f7 ...

  4. BrowserSync,调试利器--自动刷新(转

    ---恢复内容开始--- 请想象这样一个场面:你开着两个显示器,一边是IDE里的代码,另一边是浏览器里的你正在开发的应用.此时桌上还放着你的手机,手机里也是这个开发中的应用.然后,你新写了一小段代码, ...

  5. DrawDibDraw函数的使用方法

    使用windows的的自带的函数来显示图像可能始终还是绕不开两个概念, 视口和窗口. 视口--- 屏幕上的一个显示用的矩形框. 窗口--- 完整图像上的一个用于取数的矩形框. 屏幕的宽度.高度和视口参 ...

  6. JavaScript学习笔记(备忘录)

    ===运算符 判断数值和类型是否相等.如: console.log('s'==='s') //输出trueconsole.log('1'===1) //输出false

  7. hdu 3948(后缀数组+RMQ)

    题意:求一个串中有多少不同的回文串. 分析:这一题的关键是如何去重,我表示我现在还没理解为什么这样去重,先放这里过两天再看!! //不同回文子串数目 #include <iostream> ...

  8. Android UI开发详解之Fragment

    Fragment是Android自从3.0之后新加入的一个组件,我相信很多人都已经听说过这个组件了,但这个组件到底是个什么,如何去使用他呢,且听我讲来. 以下部分资料来自官网(官网才是王道,其他都是浮 ...

  9. 《C++ primer》--第7章

    删除指针后,该指针就变成了悬垂指针.悬垂指针指向曾经存放对象的内存,但该对象已经不再存在了. 习题7.8 举一个例子说明什么时候应该将形参定义为引用类型.再举一个例子说明什么时候不应该将形参定义为引用 ...

  10. IOS 时间 日历 处理集合

    1.获得当前时间 从1970开始的秒数 NSTimeInterval time = [[NSDate date[ timeIntervalSince1970]]; NSString * str = [ ...