Spring和Hibernate的整合和四种事务管理方式

在进行Spring和Hibernate整合之前先将需要的jar导入项目中:

Spring需要的jar包:

1、spring-core

2、spring-context

3、spring-jdbc

4、spring-beans

5、spring-web

6、spring-expression

7、spring-orm (spring和hibenate的整合包)

在pom.xml中编写spring3需要的包(3.1.2.RELEASE):

          <dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-expression</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring.version}</version>
		</dependency>

Hibernate需要的jar包:

        <dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>${hibernate.version}</version>
		</dependency>

数据库驱动jar包:

<!-- mysql驱动 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.1</version>
		</dependency>

添加aspectjweaver包:

<!-- 导入spring的aop需要使用到的aspectjweaver包 -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.8.5</version>
		</dependency>

导入cglib包:

	<!-- cglib包 -->
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>2.2.2</version>
		</dependency>

以上就是spring和hibernate整合需要的jar包,还有数据库连接池的jar包在等下具体说整合方式的时候在给出。

Spring和Hibernate的整合方式有两种:通过配置hibernate.cfg.xml 文件 和 在Spring配置文件中进行数据源配置;

第一种:有hibernate.cfg.xml文件进行数据源配置,在有Spring直接引用

          如果在hibernate.cfg.xml中进行数据源配置的话,必须指出hibernate.connection.provider_class属性:

	<property name="hibernate.connection.provider_class">
		org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider
	</property>

否则会报错:Cannot unwrap to requested type [javax.sql.DataSource]。然后引入hibernat-c3p0相关的jar包:

c3p0-0.9.2.1.jar,hibernate-c3p0-4.1.7.Final.jar,mchange-commons-java-0.2.3.4.jar

在pom.xml中进行配置如下(由于hibernate已经不再对dbcp提供支持,所以这里使用的是c3p0):

		<!-- 导入在hibernate指定连接池需要使用到的jar包,这里使用的是c3p0连接池 spring和hibernate整合独立使用hibernate.cfg.xml时需要指定hibernate.connection.provider_class属性的值 -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-c3p0</artifactId>
			<version>4.1.7.Final</version>
			<!-- 排除依赖的c3p0包,不然会和后面导入的jar包冲突 -->
			<exclusions>
				<exclusion>
					<groupId>c3p0</groupId>
					<artifactId>c3p0</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<!-- 如果这里groupId是c3p0则上面hibernate-c3p0则不需要进行依赖排除 -->
			<groupId>com.mchange</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.2.1</version>
		</dependency>
		<dependency>
			<groupId>com.mchange</groupId>
			<artifactId>mchange-commons-java</artifactId>
			<version>0.2.3.4</version>
		</dependency>
		<!-- 导入在hibernate指定连接池需要使用到的jar包,这里使用的是c3p0连接池 end -->

在spring配置文件中如下配置:

	<!-- 第一种配置方式:直接引用hibernate.cfg.xml文件 -->
	<bean class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
		id="sessionFactory">
		<property name="configLocation" value="hibernate.cfg.xml"></property>
	</bean>

第二种方式:在Spring中进行数据源配置

        在Spring的连接池使用同dbcp,所以需要在pom.xml中进行配置(也可以使用上面的c3p0):

<!-- 配置spring需要的连接池dbcp -->
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.2.2</version>
		</dependency>

在spring配置文件中数据源配置文件下:

	<!-- 第二种配置方式 -->
	<bean class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
		id="sessionFactory">
		<property name="dataSource" ref="dataSource"></property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.format_sql">true</prop>
				<prop key="hibernate.hbm2ddl.auto">create</prop>
			</props>
		</property>
		<property name="mappingLocations">
			<list>
				<value>实体对应的xml文件地址</value>
			</list>
		</property>
	</bean>

以上即是Spring和Hibernate整合的两种方式。

        通过上面的设置可以使得Spring和Hibernate完成整合,下面开始说Spring管理Hibernate事务的四种管理方式:

        第一种方式,利用tx标签配置事务。

	<!-- a. 配置事务容器 -->
	<bean id="txManager"
		class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>
	<!-- b. 定义事务规则 -->
	<tx:advice id="txAdvice" transaction-manager="txManager">
		<tx:attributes>
			<tx:method name="update" propagation="REQUIRED"/>
			<tx:method name="*" read-only="false" />
		</tx:attributes>
	</tx:advice>

	<!-- c. 定义事务入口(那些类的哪些方法参与事务) -->
	<aop:config>
		<aop:pointcut expression="execution(* com.cn.tch.spring_hibernate2.*.*(..))"
			id="pt" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="pt" />
	</aop:config>

下面也给出几种传播特性的解释:

1. PROPAGATION_REQUIRED: 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择;

2. PROPAGATION_SUPPORTS: 支持当前事务,如果当前没有事务,就以非事务方式执行;

3. PROPAGATION_MANDATORY: 支持当前事务,如果当前没有事务,就抛出异常;

4. PROPAGATION_REQUIRES_NEW: 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起;

5. PROPAGATION_NOT_SUPPORTED: 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起;

6. PROPAGATION_NEVER: 总是非事务地执行,如果存在一个活动事务,则抛出异常;

7. PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。

         第二种方式,使用代理进行配置

<!-- 配置事务容器 -->
	<bean id="transactionManager"
		class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	 <tx:annotation-driven transaction-manager="transactionManager" /> 
	<!-- 定义事务规则 -->
	<bean id="transactionProxy"
		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
		abstract="true">
		<property name="transactionManager" ref="transactionManager" />
		<property name="transactionAttributes">
			<props>
				<!-- ,回滚为-,不回滚为+ -->
				<prop key="update">PROPAGATION_SUPPORTS,-Exception</prop>
			</props>
		</property>
	</bean>
	<!-- 定义事务入口 -->
	<bean id="deptProxy" parent="transactionProxy">
		<property name="target" ref="deptDao"></property>
	</bean>

在使用代理管理事务时,如果需要使用到getCurrentSession()这个方法,需要设置(这里所说的有点像是第四种管理方式的配置,有可能代理模式不支持使用getCurrentSession()):

   <tx:annotation-driven transaction-manager="transactionManager" />  

同时需要在service上添加@Transactional,不然会报错:org.hibernate.HibernateException: No Session found for current thread

       第三种方式,使用拦截器

	<!-- 配置事务容器 -->
	<bean id="transactionManager"
		class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	<!-- 定义事务规则 -->
	<bean id="transactionInterceptor"
		class="org.springframework.transaction.interceptor.TransactionInterceptor">
		<property name="transactionManager" ref="transactionManager" />
		<property name="transactionAttributes">
			<props>
				<!-- 回滚为-,不回滚为+ -->
				<prop key="update">PROPAGATION_REQUIRED,-Exception</prop>
				<prop key="modify*">PROPAGATION_REQUIRED,+MyException</prop>
               
			</props>
		</property>
	</bean>
	<!-- 定义事务入口 -->
	<bean id="proxyFactory"
		class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
		<property name="interceptorNames">
			<list>
				<value>transactionInterceptor</value>
			</list>
		</property>
		<property name="beanNames">
			<list>
				<value>deptDao</value>
			</list>
		</property>
	</bean>

       第四种方式,使用注解方式

       <bean id="transactionManager"
		class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	<tx:annotation-driven transaction-manager="transactionManager" />  

同时需要在service类上面添加@Transactional。

纵观以上四种在Spring中配置Hibernate事务的方法,其核心都是一样的,不同的只是实现的方式而已。所以看到这,这篇博文中你只需要记住4句话,就可以轻松理解在Spring中配置Hibernate事务的核心:

         1.配置SessionFactory

         2.配置事务容器

         3.配置事务规则

         4.配置事务入口

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章