最近在学习hibernate时对dao设计模式产生一些疑惑,总结出以下事务管理方案:
1、只涉及到简单的业务流程(每个业务只涉及一个dao操作)
此时不需要service层,只要dao就够了。
例子:
public void insertUser(Users user) {
Session session=SessionFactory.openSession();
Transaction ts=session.beginTransaction();
session.save(user);
ts.commit();
session.close();
}
这里的SessionFactory.openSession()每次都打开一个新的session。session的关闭也可以配置为事务提交后自动关闭:
<property name="hibernate.transaction.auto_close_session">true</property>
2、业务流程复杂,一个业务中涉及多个dao操作,此时可使用绑定到JDBC事务的方法,还可以使用JTA事务(依赖于容器),也可以选择spring事务拦截器,由spring管理更好,可以从session、事务的管理中解脱出来。
1)将session绑定到JDBC事务上实现:
若一个事务中涉及多个dao操作,就需要将session绑定到JDBC事务,使得当前事务中获取的session都是同一个session,保证事务完整。
使用SessionFactory.getCurrentSession()取得与当前JDBC事务关联的session。
session的打开与关闭无需关心,由hibernate管理。
注意需要配置:
<property name="current_session_context_class">thread</property>
而且在查询时也必须开启一个事务,否则报错。
这样在一个事务中调用多个dao操作,各个dao中的session都是同一个session。
一个包含了多个dao操作的业务层代码如下:
//模拟转账
public void transfer(){
Transaction ts=SessionFactory.getCurrentSession().beginTransaction();
accoutDao.add("accout_A",100);
accoutDao.add("accout_B",-100);
ts.commit();
}
上面是基于配置方式绑定session到JDBC事务,也可以使用局部线程变量,达到公用同一个session的目的,实现多dao操作的事务管理。此时getSession()方法如下:
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession()
: null;
threadLocal.set(session);
}
return session;
}
这样,在一个事务里面不同dao中拿到的session其实是一个session(与当前事务关联),而且查询时不需要开启事务,不需要配置<property name="current_session_context_class">thread</property>。
Demo:
dao层
public void add(String id,double number) {
Session s = SessionFactory.getSession();
Account acc=s.get(Account.Class,id);
acc.setBalance(acc.getBalance()+number);
s.update(acc);
}
业务层:
public void transfer(){
Transaction ts=SessionFactory.getSession().beginTransaction();
accoutDao.add("accout_A",100);
accoutDao.add("accout_B",-100);
ts.commit();
}
两个dao操作任何一个失败,事务都不会提交(提交之前就发生了异常),保持数据一致。
这样将事务管理放在业务层,dao层只需做原始的CRUD即可,无需关心事务和session。
但是这样有一个明显的缺点:事务失败后需要手动关闭session,因为session配置为自动关闭是当事务正确提交时或者失败回滚时才会自动关闭session(使用getCurrentSession()的不需要这样,但查询也要开启事务)。
所以我们这里再讨论一下spring的事务管理方式,很方便。。。
2)使用Spring实现:
spring配置:
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean" destroy-method="close">
<property name="jndiName">
<value>java:comp/env/jdbc/pingshen</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.SQLServerDialect
</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>com/cjlu/vo/Users.hbm.xml</value>
</list>
</property>
</bean>
<bean id="hibernateTemplate"
class="org.springframework.orm.hibernate3.HibernateTemplate" abstract="true">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<!-- 配置事务拦截器 -->
<bean id="txInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<!-- 定义事务传播属性 -->
<props>
key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- 配置自动代理 -->
<bean
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<!-- 这里可以新增要代理的业务bean-->
<value>userService</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>txInterceptor</value>
</list>
</property>
</bean>
<bean id="userService"
class="com.cjlu.service.impl.UserServiceImpl">
<property name="userDao">
<bean class="com.cjlu.dao.impl.UserDaoImpl" parent="hibernateTemplate">
</bean>
</property>
</bean>
注意:此时需要spring的IOC(依赖注入),即每个DaoImpl实现类需要继承HibernateDaoSupport类,并在spring配置文件注入hibernateTemplate,为HibernateDaoSupport中的hibernateTemplate属性绑定hibernate模板。
另外,Action中需要注入Service以便调用,不要在DaoImpl中lookup(datasource),以保证事务的完整性。
DaoImpl中从父类HibernateDaoSupport中继承了getSession()方法,只要使用了Spring声明式事务,用完后不需要关闭,DaoImpl只负责原始的数据操作。
分享到:
相关推荐
Spring 框架则更像一个全能选手,它不仅支持 MVC 架构,还提供了依赖注入(DI)、面向切面编程(AOP)、事务管理、数据访问集成等众多功能。Spring 的核心是 IoC(Inversion of Control)容器,它负责创建和管理对象...
《Hibernate学习笔记特别详细》 Hibernate,作为一款开源的Object-Relational Mapping(ORM)框架,为Java开发者提供了强大的数据库操作支持。它简化了数据库访问的复杂性,使得开发人员可以像操作对象一样操作...
Hibernate学习笔记整理 以下是 Hibernate 框架的详细知识点: Hibernate 介绍 Hibernate 是一个 ORM(Object-Relational Mapping)框架,用于将 Java 对象映射到数据库表中。它提供了一个简洁的方式来访问和操作...
在本篇“Spring Hibernate 事务管理学习笔记(二)”中,我们将深入探讨Spring框架与Hibernate集成时如何实现高效、安全的事务管理。这是一篇关于源码分析和技术工具使用的文章,适合对Java开发和数据库操作有基础...
【标题】"hibernate学习笔记-01helloworld"主要涵盖了Hibernate框架的基础入门知识,是初学者了解和掌握Hibernate的重要起点。Hibernate是一款强大的Java对象关系映射(ORM)框架,它简化了数据库操作,使得开发者...
在本篇《Hibernate学习笔记》中,我们将深入...以上就是Hibernate学习笔记的一些核心概念和操作示例,涵盖了数据的增删查改以及事务管理。通过理解和实践这些知识点,开发者可以更有效地利用Hibernate进行数据库操作。
【Hibernate学习笔记(1-13)】是传智播客李勇的教程,涵盖了Hibernate框架的基础到进阶内容。Hibernate是一个流行的ORM(对象关系映射)框架,它旨在解决Java面向对象编程与关系型数据库之间的模型不匹配问题,即...
【Java相关课程系列笔记之十四Hibernate学习笔记】 Hibernate是一个开源的对象关系映射(ORM)框架,它极大地简化了Java应用程序对数据库的操作。本笔记将详细阐述Hibernate的核心概念、使用方法和特性。 一、...
**Hibernate学习笔记与总结** Hibernate 是一款开源的对象关系映射(ORM)框架,它为Java开发者提供了一种在关系数据库上操作对象数据的便捷方式。本文将深入探讨Hibernate的核心概念、配置、实体类、映射文件、...
### Hibernate—我的Hibernate学习笔记 #### 一、对象持久化的理论与实践 ##### 对象持久化概念 对象持久化指的是将内存中的对象状态保存至外部持久性存储设备(如硬盘),以便于日后需要时能够恢复其状态。这一...
### 马士兵Hibernate学习笔记知识点总结 #### 一、课程内容概览 - **HelloWorld**:通过简单的示例程序介绍如何启动一个基于Hibernate的Java项目。 - **Hibernate原理模拟**:解释O/R Mapping的概念及其重要性。 -...
在学习过程中,阅读博客如《spring hibernate 事务管理学习笔记(一)》是非常有益的,它通常会包含具体的示例代码和实践建议。你可以参考这个博客链接(https://microjava.iteye.com/blog/525973),结合实际项目,...
### Hibernate 学习笔记知识点概览 #### 一、Hibernate 概述 - **定义**:Hibernate 是一款开源的对象关系映射(ORM)框架,它实现了将 Java 应用程序中的对象模型映射到关系型数据库中的记录。通过 ORM 技术,...
Hibernate是一款强大的Java持久...通过阅读这份“Hibernate API帮助文档”和“Hibernate学习笔记”,你将能够深入理解Hibernate的工作原理,掌握其API的使用,并能在实际项目中有效地利用Hibernate进行数据持久化操作。
接下来是“马士兵hibernate学习笔记.doc”。Hibernate是一个对象关系映射(ORM)框架,它简化了Java应用对数据库的操作。Hibernate允许开发者使用Java对象来操作数据库记录,减少了SQL的编写工作。笔记可能讲解了...
根据提供的信息,我们可以总结出以下关于达内HIBERNATE学习笔记的重要知识点: ### 第一章:Hibernate入门 #### 1.1 学习目标 - 理解Hibernate的基本概念。 - 掌握如何使用Hibernate进行开发。 #### 1.2 对象持久...
**Hibernate学习笔记与大纲** Hibernate 是一款开源的Java语言下的对象关系映射(ORM)框架,它极大地简化了数据库操作,使得开发人员可以使用面向对象的方式处理数据,而无需过多关注底层的SQL语句。本笔记将深入...
### 马士兵 Hibernate 学习笔记概览 #### 一、Hello World 示例 - **简介**:通过简单的示例程序来快速入门 Hibernate 框架。 - **步骤**: 1. 创建 Java 项目 `hibernate_0100_HelloWorld`。 2. 构建 User-...
本学习笔记将深入探讨Hibernate的核心概念、配置、实体映射、查询语言以及事务管理等方面的知识。 一、Hibernate概述 Hibernate 是基于Java的持久化框架,它消除了Java应用程序与数据库之间的直接交互,通过对象...