Spring -- spring 和 hibernate 整合
1.概述, 事务管理, 编程式和说明式事务管理
2. 事务属性
传播行为:
|
传播行为 |
意义 |
|
PROPAGATION_MANDATORY |
该方法必须运行在一个事务中。如果当前事务不存在,将抛出一个异常。 |
|
PROPAGATION_NESTED |
若当前已经存在一个事务,则该方法应当运行在一个嵌套的事务中。被嵌套的事务可以从当前事务中单独的提交或回滚。若当前事务不存在,则看起来就和PROPAGATION_REQUIRED没有两样。 |
|
PROPAGATION_NEVER |
当前的方法不应该运行在一个事务上下文中。如果当前存在一个事务,则会抛出一个异常。 |
|
PROPAGATION_NOT_SUPPORTED |
表示该方法不应在事务中运行。如果一个现有的事务正在运行,他将在该方法的运行期间被挂起。如果使用jta的事务管理器,需要访问jtatansactionmanager. |
|
传播行为 |
意义 |
|
PROPAGATION_REQUIRED |
表示当前方法必须运行在一个事务中。若一个现有的事务正在进行中,该方法将会运行在这个事务中。否则的话,就要开一个新的事务。 |
|
PROPAGATION_REQUIRES_NEW |
表示当前方法必须运行在它自己的事务里。他将启动一个新的事务。如果一个现有事务在运行的话,将在这个方法运行期间被挂起。若使用jtaTransactionManager,则需要访问transactionManager |
|
PROPAGATION_SUPPORTS |
当前方法不需要事务处理环境,但如果有一个事务已经在运行的话,这个方法也可以在这个事务里运行。 |
隔离级别
|
隔离级别 |
含义 |
|
ISOlATION_DEFAULT |
使用后端数据库默认的隔离级别 |
|
ISOLATION_READ_UNCOMMITED |
允许你读取还未提交后数据。可能导致脏、幻、不可重服 |
|
ISOLATION_READ_COMMITTED |
允许在并发事务已经提交后读取。可防止脏读,但幻读和 不可重复读仍可发生。 |
|
ISOLATION_REPEATABLE_READ |
对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏、不可重复读,幻读仍可能发生。 |
|
ISOLATION_SERIALABLE |
完全服从ACID的隔离级别,确保不发生脏、幻、不可重复读。这在所有的隔离级别中是最慢的,它是典型的通过完全锁定在事务中涉及的数据表来完成的。 |
只读
若对数据库只进行读操作,可设置事务只读的属性,使用某些优化措施。数据库会进行优化处理。若使用hibernate作为持久化机制,声明一个只读事务会使hibernate的flush模式设置为FLUSH_NEVER。避免不必要的数据同步,将所有更新延迟到事务的结束。
事务超时
若事务在长时间的运行,会不必要的占用数据库资源。设置超时后,会在指定的时间片回滚。将那些具有可能启动新事务的传播行为的方法的事务设置超时才有意义(PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW,PROPAGATION_NESTED)。
回滚规则
3. 示例代码
Customer.java, javabean 对象
public class Customer {
private Integer id ;
private String name ;
private Integer age ;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
Customer.hbm.xml ,映射配置文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.itcast.spring.domain.Customer" table="customers" lazy="false">
<id name="id" column="id" type="integer">
<generator class="identity" />
</id>
<property name="name" column="name" type="string" not-null="true"/>
<property name="age" column="age" type="integer" />
</class>
</hibernate-mapping>
CustomerDao.java, dao层接口
public interface CustomerDao {
public void insertCustomer(Customer c);
public void updateCustomer(Customer c);
public List<Customer> findCustomerByName(String name);
//批量保存
//public void saveCustomers(List<Customer> list);
}
CustomerDaoImpl.java,dao接口 模板实现
/**
* CustomerDaoImpl
*/
public class CustomerDaoImpl implements CustomerDao {
//hibernate模板,封装样板代码
private HibernateTemplate ht ;
public void setHt(HibernateTemplate ht) {
this.ht = ht;
} public List<Customer> findCustomerByName(String name) {
String hql = "from Customer c where c.name = ?";
return ht.find(hql, name);
} public void insertCustomer(Customer c) {
ht.save(c);
} public void updateCustomer(Customer c) {
ht.update(c);
} /**
* 批量保存
*/
// public void saveCustomers(final List<Customer> list) {
// ht.execute(new HibernateCallback(){
// public Object doInHibernate(Session session)
// throws HibernateException, SQLException {
// Transaction tx = null;
// try {
// tx = session.beginTransaction();
// for(Customer c : list){
// session.save(c);
// }
// tx.commit();
// } catch (Exception e) {
// tx.rollback();
// e.printStackTrace();
// }
// return null;
// }});
// }
}
CustomerDaoSupportImpl.java , dao接口 HibernateDaoSupport 实现
/**
* CustomerDaoImpl
*/
public class CustomerDaoSupportImpl extends HibernateDaoSupport implements CustomerDao { public List<Customer> findCustomerByName(String name) {
String hql = "from Customer c where c.name = ?";
return getHibernateTemplate().find(hql, name);
} public void insertCustomer(Customer c) {
getHibernateTemplate().save(c);
} public void updateCustomer(Customer c) {
getHibernateTemplate().update(c);
} public void saveCustomers(List<Customer> list) {
// TODO Auto-generated method stub }
}
CustomerService.java,service层接口
public interface CustomerService {
public void insertCustomer(Customer c);
public void updateCustomer(Customer c);
public List<Customer> findCustomerByName(String name);
//批量保存
public void saveCustomers(List<Customer> list);
}
CustomerServiceImpl.java, service层接口实现, 编程式事务管理
public class CustomerServiceImpl implements CustomerService {
//dao
private CustomerDao dao ;
//事务模板,封装事务管理的样板代码
private TransactionTemplate tt ;
//注入事务模板
public void setTt(TransactionTemplate tt) {
this.tt = tt;
}
//注入dao
public void setDao(CustomerDao dao) {
this.dao = dao;
}
public List<Customer> findCustomerByName(String name) {
return dao.findCustomerByName(name);
}
public void insertCustomer(Customer c) {
dao.insertCustomer(c);
}
/**
* 批量保存, 编程式事务管理
*/
public void saveCustomers(final List<Customer> list) {
// for(Customer c : list){
// dao.insertCustomer(c);
// }
tt.execute(new TransactionCallback(){
public Object doInTransaction(TransactionStatus status) {
try {
for(Customer c : list){
dao.insertCustomer(c);
}
} catch (RuntimeException e) {
e.printStackTrace();
//设置回滚
status.setRollbackOnly();
}
return null;
}});
}
public void updateCustomer(Customer c) {
dao.updateCustomer(c);
}
}
CustomerServiceDeclareImpl.java , service层接口实现, 声明式事务管理
/**
* 声明式事务管理,通过aop框架实现
*/
public class CustomerServiceDeclareImpl implements CustomerService {
//dao
private CustomerDao dao ; //注入dao
public void setDao(CustomerDao dao) {
this.dao = dao;
} public List<Customer> findCustomerByName(String name) {
return dao.findCustomerByName(name);
} public void insertCustomer(Customer c) {
dao.insertCustomer(c);
} /**
* 批量保存, 编程式事务管理
*/
public void saveCustomers(final List<Customer> list) {
for(Customer c : list){
dao.insertCustomer(c);
}
} public void updateCustomer(Customer c) {
dao.updateCustomer(c);
}
}
jdbc.properties, 数据库配置信息
jdbc.driverclass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring
jdbc.username=root
jdbc.password=root c3p0.pool.size.max=10
c3p0.pool.size.min=2
c3p0.pool.size.ini=3
c3p0.pool.size.increment=2 hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=none
sh.xml, spring配置文件,编程式
<?xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd ">
<!-- 指定分散配置的文件的位置 -->
<context:property-placeholder location="classpath:cn/itcast/spring/hibernate/jdbc.properties"/>
<!-- 配置c3p0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverclass}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" /> <property name="maxPoolSize" value="${c3p0.pool.size.max}" />
<property name="minPoolSize" value="${c3p0.pool.size.min}" />
<property name="initialPoolSize" value="${c3p0.pool.size.ini}" />
<property name="acquireIncrement" value="${c3p0.pool.size.increment}" />
</bean> <!-- 本地回话工厂bean,spring整合hibernate的核心入口 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 指定hibernate自身的属性 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
<!-- 方式一:映射资源文件的位置
<property name="mappingResources">
<list>
<value>classpath:cn/itcast/spring/domain/Customer.hbm.xml</value>
</list>
</property>
-->
<!--方式二-->
<property name="mappingDirectoryLocations">
<list>
<value>classpath:cn/itcast/spring/domain</value>
</list>
</property>
<!--方式二:使用hibernate自身的配置文件配置
<property name="configLocations">
<list>
<value>classpath:hibernate.cfg.xml</value>
</list>
</property>
-->
</bean> <!-- hibernate模板,封装样板代码 -->
<bean id="ht" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean> <!-- customerDao -->
<bean id="customerDao" class="cn.itcast.spring.hibernate.CustomerDaoImpl">
<property name="ht" ref="ht" />
</bean> <!-- hibernate事务管理器,在service层面上实现事务管理,而且达到平台无关性 -->
<bean id="htm" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean> <!-- 事务模板,封装了事务管理的样板代码 -->
<bean id="tt" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="htm" />
</bean>
<!-- customerService -->
<bean id="customerService" class="cn.itcast.spring.hibernate.CustomerServiceImpl">
<property name="dao" ref="customerDao" />
<property name="tt" ref="tt" />
</bean> <!-- ************************ daoSupport ******************** -->
<bean id="customerDaoSupport" class="cn.itcast.spring.hibernate.CustomerDaoSupportImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
shDeclare.xml, spring配置文件,声明式
<?xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd ">
<!-- 指定分散配置的文件的位置 -->
<context:property-placeholder location="classpath:cn/itcast/spring/hibernate/jdbc.properties"/>
<!-- 配置c3p0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverclass}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" /> <property name="maxPoolSize" value="${c3p0.pool.size.max}" />
<property name="minPoolSize" value="${c3p0.pool.size.min}" />
<property name="initialPoolSize" value="${c3p0.pool.size.ini}" />
<property name="acquireIncrement" value="${c3p0.pool.size.increment}" />
</bean> <!-- 本地回话工厂bean,spring整合hibernate的核心入口 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 指定hibernate自身的属性 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
<!-- 映射资源文件的位置
<property name="mappingResources">
<list>
<value>classpath:cn/itcast/spring/domain/Customer.hbm.xml</value>
</list>
</property>
-->
<property name="mappingDirectoryLocations">
<list>
<value>classpath:cn/itcast/spring/domain</value>
</list>
</property>
<!-- 使用hibernate自身的配置文件配置
<property name="configLocations">
<list>
<value>classpath:hibernate.cfg.xml</value>
</list>
</property>
-->
</bean> <!-- hibernate模板,封装样板代码 -->
<bean id="ht" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean> <!-- customerDao -->
<bean id="customerDao" class="cn.itcast.spring.hibernate.CustomerDaoImpl">
<property name="ht" ref="ht" />
</bean> <!-- hibernate事务管理器,在service层面上实现事务管理,而且达到平台无关性 -->
<bean id="htm" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean> <!-- customerService,目标对象 -->
<bean id="customerServiceTarget" class="cn.itcast.spring.hibernate.CustomerServiceDeclareImpl">
<property name="dao" ref="customerDao" />
</bean> <!-- 代理对象 -->
<bean id="customerService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!-- 注入事务管理器 -->
<property name="transactionManager" ref="htm" />
<property name="proxyInterfaces">
<list>
<value>cn.itcast.spring.hibernate.CustomerService</value>
</list>
</property>
<property name="target" ref="customerServiceTarget" />
<!-- 事务属性集(设置事务策略的), 事务属性:传播行为,隔离级别,只读,超时,回滚规则 -->
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop>
<prop key="update*">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop>
<prop key="delete*">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop>
<prop key="insert*">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop> <!--对数据库只进行读操作,可设置事务只读的属性,使用某些优化措施。数据库会进行优化处理。-->
<prop key="load*">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly</prop>
<prop key="get*">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly</prop> <prop key="*">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly</prop> </props>
</property>
</bean>
</beans>
AppService.java 测试代码1
public class AppService {
public static void main(String[] args) throws SQLException {
ApplicationContext ac = new ClassPathXmlApplicationContext(
"cn/itcast/spring/hibernate/sh.xml");
CustomerService cs = (CustomerService) ac.getBean("customerService");
List<Customer> list = new ArrayList<Customer>();
Customer c = null ;
for(int i = 0 ; i < 10 ; i++){
c = new Customer();
if(i == 9){
c.setName(null);
}
else{
c.setName("tom" + i);
}
c.setAge(20 + i);
list.add(c);
}
cs.saveCustomers(list);
}
}
AppServiceDeclare.java 测试代码二
public class AppServiceDeclare {
public static void main(String[] args) throws SQLException {
ApplicationContext ac = new ClassPathXmlApplicationContext(
"cn/itcast/spring/hibernate/shDeclare.xml");
CustomerService cs = (CustomerService) ac.getBean("customerService");
List<Customer> list = new ArrayList<Customer>();
Customer c = null ;
for(int i = 0 ; i < 10 ; i++){
c = new Customer();
if(i == 9){
c.setName(null);
}
else{
c.setName("tom" + i);
}
c.setAge(20 + i);
list.add(c);
}
cs.saveCustomers(list);
}
}
Spring -- spring 和 hibernate 整合的更多相关文章
- Java Web开发之Spring | SpringMvc | Mybatis | Hibernate整合、配置、使用
1.Spring与Mybatis整合 web.xml: <?xml version="1.0" encoding="UTF-8"?> <web ...
- 轻量级Java EE企业应用实战(第4版):Struts 2+Spring 4+Hibernate整合开发(含CD光盘1张)
轻量级Java EE企业应用实战(第4版):Struts 2+Spring 4+Hibernate整合开发(含CD光盘1张)(国家级奖项获奖作品升级版,四版累计印刷27次发行量超10万册的轻量级Jav ...
- Spring + Spring MVC+Hibernate框架整合详细配置
来源于:http://www.jianshu.com/p/8e2f92d0838c 具体配置参数: Spring: spring-framework-4.2.2Hibernate: hibernate ...
- java框架篇---spring hibernate整合
在会使用hibernate 和spring框架后 两个框架的整合就变的相当容易了, 为什么要整合Hibernate?1.使用Spring的IOC功能管理SessionFactory对象 LocalSe ...
- Struts+Spring+Hibernate整合入门详解
Java 5.0 Struts 2.0.9 Spring 2.0.6 Hibernate 3.2.4 作者: Liu Liu 转载请注明出处 基本概念和典型实用例子. 一.基本概念 St ...
- Spring与Hibernate整合,实现Hibernate事务管理
1.所需的jar包 连接池/数据库驱动包 Hibernate相关jar Spring 核心包(5个) Spring aop 包(4个) spring-orm-3.2.5.RELEASE.jar ...
- spring+hibernate整合:报错org.hibernate.HibernateException: No Session found for current thread
spring+hibernate整合:报错信息如下 org.hibernate.HibernateException: No Session found for current thread at o ...
- Spring与Hibernate整合中,使用OpenSessionInViewFilter后出现sessionFactory未注入问题
近期在知乎看到一句话,保持学习的有一种是你看到了很多其它的牛人,不甘心,真的不甘心. Spring和hibernate整合的时候,jsp页面做展现,发现展现属性出现: org.apache.jaspe ...
- 框架篇:Spring+SpringMVC+hibernate整合开发
前言: 最近闲的蛋疼,搭个框架写成博客记录下来,拉通一下之前所学知识,顺带装一下逼. 话不多说,我们直接步入正题. 准备工作: 1/ IntelliJIDEA的安装配置:jdk/tomcat等..(本 ...
- Spring第九篇【Spring与Hibernate整合】
前言 前面已经学习了如何使用Spring与Struts2进行整合,本博文主要讲解如何使用Spring对Hibernate进行整合 Spring和Hibernate整合的关键点: SessionFact ...
随机推荐
- 穿透Session 0 隔离(二)
上一篇我们已经对Session 0 隔离有了进一步认识,如果在开发过程中确实需要服务与桌面用户进行交互,可以通过远程桌面服务的API 绕过Session 0 的隔离完成交互操作. 对于简单的交互,服务 ...
- 视频流协议HLS与RTMP 直播原理 点播原理
小结: 1.HLS原理 视频--->图像.声音分别编码打包切割容器文件ts,建立纯文本索引文件.m3u8--->播放器http下载容器文件.索引文件,播放,下载 基于HLS可以实现直播和点 ...
- :nohlsearch
vim 编辑器 ——黄色阴影的消除问题 - leikun153的博客 - CSDN博客 https://blog.csdn.net/leikun153/article/details/78903597 ...
- IO流入门-第八章-BufferedWriter
BufferedWriter基本用法和方法示例 import java.io.*; public class BufferedWriterTest01 { public static void mai ...
- java工程编写manifest文件
如果需要一个可以单独运行的jar包“Runnable JAR file”,省事的方法是妥妥的选择打一个可运行的jar包“Runnable JAR file”.如此一来,就可以把程序运行所依赖的类.第三 ...
- MFC DLL获取当前路径
.首先定义此获取模块的静态方法 #if _MSC_VER >= 1300 // for VC 7.0 // from ATL 7.0 sources #ifndef _delayimp_h ex ...
- QStorageInfo获取磁盘信息(非常详细)
QStorageInfo类提供了系统当前挂载的存储和驱动器的相关信息,包括它们的空间,挂载点,标签名,文件系统名. 一般,我们可以使用特定的文件或目录来创建一个QStorageInfo类的对象,也可以 ...
- JS改变HTML元素的绝对坐标
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DT ...
- js生成二维码/html2canvas生成屏幕截图
1.需求简述 (1) 最初需求: 根据后台接口获取url,生成一个二维码,用户可以长按保存为图片.(这时的二维码只是纯黑白像素构成的二维码) 方案1: 使用jquery.qrcode.min.js插件 ...
- 我的Android进阶之旅------>Java字符串格式化方法String.format()格式化float型时小数点变成逗号问题
今天接到一个波兰的客户说有个APP在英文状态下一切运行正常,但是当系统语言切换到波兰语言的时候,程序奔溃了.好吧,又是我来维护. 好吧,先把系统语言切换到波兰语,切换到波兰语的方法查看文章 我的And ...