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.配置事務入口

 

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