在进行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.配置事务入口