1 整合Hibernate事務控制
1.1 了解事務
我們一般說的事務是來源於關系數據庫,當有數據持久化需求時一般都需要事務控制。
關系數據庫:支持事務控制,mysql數據庫存儲引擎為InnoDB支持事務,存儲引擎為MyIsam不支持事務。
jdbc:支持事務控制,設置CommitAuto(false)
Hibernate:支持事務,使用session.beginTransaction(),再session.getTransaction().commit()提交事務
spring如果控制事務:由於使用hibernate,spring對Hibernate中session進行管理,支持事務。
1.2 HibenateTemplate
spring針對持久層框架提供了模板類封裝數據庫操作方法:
1、可以簡化數據訪問的開發
2、支持事務控制,spring對Hibernate中session進行管理
spring提供了很多模板:
1、JdbcTemplate,針對jdbc操作數據庫模板,相當於DbUtil
2、HibernateTemplate,針對Hibernate操作數據庫模板。
1.3 加入jar
spring-orm-4.2.4.RELEASE.jar:spring針對orm框架整合包
spring-tx-4.2.4.RELEASE.jar:spring提供事務管理的包
spring-jdbc-4.2.4.RELEASE.jar:spring提供jdbc操作方法包,此包為事務控制的基礎包
1.4 測試HibenateTemplate
1.4.1dao
dao實現類繼承HibenrateDaoSupport(選擇hibernate對應版本,一般選第5版)
1.4.2 配置dao
<bean id="customerTestDao" class="cn.itcast.crm.dao.impl.CustomerTestDaoImpl">
</bean>
運行報錯:
'sessionFactory' or 'hibernateTemplate' is required
由於dao繼承HibernateDaoSupport運行需要'sessionFactory'或'hibernateTemplate'。
解決:
將'sessionFactory' or 'hibernateTemplate'注入到dao中。
<!-- 加載db.properties配置文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- -->
<bean id="customerTestDao" class="cn.itcast.crm.dao.impl.CustomerTestDaoImpl">
<property name="hibernateTemplate" ref="hibernateTemplate"/>
</bean>
<!-- hibernateTemplate,依賴了sessionFactory -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 配置 sessionFactory,依賴dataSource數據源(數據庫連接池)-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- 數據源 -->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- spring對 數據源進行管理 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- mysql的驅動包 -->
<property name="driverClass" value="${jdbc.driver}" />
<!-- 連接數據庫url -->
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
報錯:
Unable to locate persister: cn.itcast.crm.domain.CstCustomer
CstCustomer不是一個被hibenate管理的實體類型。
解決:
在創建SessionFacotry時候加載Hibenate 映射文件:
以上是和hibernate框架進行整合,
2基於aop使用聲明式事務控制
2.1 什么是aop
當前service開發中問題:
每個需要進行事務控制的service代碼中事務控制部分代碼重復的代碼,將這些事務控制重復的代碼抽取出來。
解決方法:
采用spring aop面向切面編程對上邊的代碼進行抽取
AOP( Aspect Oriented Programing) 面向切面編程。Spring1.2 版本開始支持AOP編程 (面向切面編程 )。
采用aop的方法對類代碼切面編程,通過橫向抽取方法將service中的事務控制的代碼抽取出來。
2.2 aop的原理
aop面向切面編程的原理就是代理:
1、靜態代理
采用一些工具類對原來的類生成一個代理類,代理類以.class存在
2、動態代理(重點,spring基於動態代理實現aop)
在運行中,通過反射生成類的代理對象,在代理對象中對原來的對象進行增強。
spring采用動態代理的技術包括:
1、基於接口生成代理對象(重點)
根據接口方法生成代理對象,對原來的代理對象進行增強
使用jdk提供反射實現
2、基於類生成代理對象
根據類生成一個子類(代理對象),在代理對象(子類)中對父類進行增強。
使用CGLib實現
編寫原始類:
public interface CustomerServiceAop {
public void insertCustomer(CstCustomer cstCustomer,CstCustomerDetail cstCustomerDetail) ;
}
了解jdk和cglib區別
jdk:基於接口生成代理對象
cglib:基於類生成代理對象
spring底層使用jdk和cglib,如果原始對象實現了一個接口,spring使用jdk,否則 使用cglib生成代理。
AOP聯盟
AOP聯盟出一套aop的標准。
aop聯盟的jar包:
aop術語:
Pointcut(切入點):確定在哪個方法上增強,一個類有多個切點
Advice(通知/增強):在切點上進行增強,包括:前置增強、后置增強、拋出異常增強
Target(目標對象):對目標對象進行增強,生成代理對象
Proxy(代理):對目標對象進行增強,生成代理對象
Weaving(織入):生成代理的時機(過程)
1、動態代理織入,在運行期為目標類生成代理對象
2、編譯期織入
Aspect(切面): 包括切點和增強,面向哪個切點進行增強(編程)。
AspectJ語法(切點語法):
通過語法配置切入點:
切入點:方法,哪個/此類哪個/些方法
表達式包括兩部分:函數名和操作參數。
例子:execution(* cn.itcast.spring.service.impl.*.*(..)) 匹配cn.itcast.spring.service.impl包下所有類的所有方法(任意形參),任意返回值。
增強
AspectJ支持的增強類型:
n Before 前置增強/通知,相當於BeforeAdvice
n AfterReturning 后置增強/通知,相當於AfterReturningAdvice
n Around 環繞增強/通知,相當於MethodInterceptor
n AfterThrowing拋出增強/通知,相當於ThrowAdvice
After 最終finally增強/通知,不管是否異常,該通知都會執行
下面就開始逐層配置:
dao:
還是用上面寫好的繼承hibernamteTemplate
service:
事務管理器
在applicatoinContext-transaction.xml
配置增強(實現事務 管理)
加入約束:
<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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 切面
包括:切點和增強
-->
<aop:config>
<!-- 使用aop:advisor配置切面,和 tx:advice配置使用實現事務控制
advice-ref :指定引用增強
-->
<aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.itcast.crm.service.impl.*.*(..))"/>
</aop:config>