1. 程式人生 > >Spring相關知識

Spring相關知識

Spring Spring框架 1.1.1 Spring的概述: 1.1.1.1 什麼是Spring :

Spring是一個開源框架,Spring是於2003 年興起的一個輕量級的Java 開發框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中闡述的部分理念和原型衍生而來。它是為了解決企業應用開發的複雜性而建立的。框架的主要優勢之一就是其分層架構,分層架構允許使用者選擇使用哪一個元件,同時為 J2EE 應用程式開發提供整合的框架。Spring使用基本的JavaBean來完成以前只可能由EJB完成的事情。然而,Spring的用途不僅限於伺服器端的開發。從簡單性、可測試性和鬆耦合的角度而言,任何Java應用都可以從Spring中受益。Spring的核心是控制反轉(IoC)和麵向切面(AOP)。簡單來說,Spring是一個分層的JavaSE/EEfull-stack(一站式) 輕量級開源框架。

EE開發分成三層結構:

  • WEB層:Spring MVC.
  • 業務層:Bean管理:(IOC)
  • 持久層:Spring的JDBC模板.ORM模板用於整合其他的持久層框架.

Expert One-to-One J2EE Design and Development :J2EE的設計和開發:(2002.EJB) Expert One-to-One J2EE Development without EJB :J2EE不使用EJB的開發. 1.1.1.2 為什麼學習Spring: 方便解耦,簡化開發 Spring就是一個大工廠,可以將所有物件建立和依賴關係維護,交給Spring管理 AOP程式設計的支援 Spring提供面向切面程式設計,可以方便的實現對程式進行許可權攔截、執行監控等功能 宣告式事務的支援 只需要通過配置就可以完成對事務的管理,而無需手動程式設計 方便程式的測試 Spring對Junit4支援,可以通過註解方便的測試Spring程式 方便整合各種優秀框架 Spring不排斥各種優秀的開源框架,其內部提供了對各種優秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支援 降低JavaEE API的使用難度 Spring 對JavaEE開發中非常難用的一些API(JDBC、JavaMail、遠端呼叫等),都提供了封裝,使這些API應用難度大大降低 1.1.1.3 Spring的版本: Spring 3.X 和 Spring4.X 1.1.2 Spring的入門案例:(IOC) 1.1.2.1 IOC的底層實現原理

  • docs :API和開發規範.
  • libs :jar包和原始碼.
  • schema :約束. 1.1.2.3 步驟二:建立web專案,引入Spring的開發包:

1.1.2.4 步驟三:引入相關配置檔案: log4j.properties applicationContext.xml 引入約束: spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html

1.1.2.5 步驟四:編寫相關的類: public interface UserDao {
public void sayHello();

}

public class UserDaoImpl implements UserDao {

@Override
public void sayHello() {
	System.out.println("Hello Spring...");
}

} 1.1.2.6 步驟五:完成配置:

1.1.2.7 步驟六:編寫測試程式: @Test // Spring的方式: public void demo2(){ // 建立Spring的工廠類: ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“applicationContext.xml”); // 通過工廠解析XML獲取Bean的例項. UserDao userDao = (UserDao) applicationContext.getBean(“userDao”); userDao.sayHello(); } 1.1.2.8 IOC和DI: IOC :控制反轉,將物件的建立權交給了Spring. DI :Dependency Injection 依賴注入.需要有IOC建立物件的環境,Spring建立這個類的過程中,Spring將類的依賴的屬性值(基本型別和物件型別)設定進去.

1.1.3 Spring中的工廠: 1.1.3.1 ApplicationContext: ApplicatioContext介面有兩個實現類:

ClassPathXmlApplicationContext :載入類路徑下Spring的配置檔案. FileSystemXmlApplicationContext :載入本地磁碟下Spring的配置檔案. 1.1.3.2 BeanFactory:

1.1.3.3 BeanFactory和ApplicationContext的區別: BeanFactory :是在getBean的時候才會生成類的例項. ApplicationContext :在載入applicationContext.xml時候就會建立. 1.1.4 配置STS的XML的提示: 1.1.4.1 Spring配置檔案中提示的配置 複製路徑:

點選Add…

1.1.5 Spring的相關配置: 1.1.5.1 id屬性和name屬性標籤的配置 id :Bean起個名字. 在約束中採用ID的約束:唯一. 必須以字母開始,可以使用字母、數字、連字元、下劃線、句話、冒號 id:不能出現特殊字元. name:Bean起個名字. 沒有采用ID的約束. name:出現特殊字元.如果沒有id的話 , name可以當做id使用.

  • 整合struts1的時候:

1.1.5.2 scope屬性:Bean的作用範圍.

  • singleton :預設值,單例的.
  • prototype :多例的.
  • request :WEB專案中,Spring建立一個Bean的物件,將物件存入到request域中.
  • session :WEB專案中,Spring建立一個Bean的物件,將物件存入到session域中.
  • globalSession :WEB專案中,應用在Porlet環境.如果沒有Porlet環境那麼globalSession相當於session.

1.1.5.3 Bean的生命週期的配置: 通過配置標籤上的init-method作為Bean的初始化的時候執行的方法,配置destroy-method作為Bean的銷燬的時候執行的方法。 銷燬方法想要執行,需要是單例建立的Bean而且在工廠關閉的時候,Bean才會被銷燬. 1.1.6 Spring的Bean的管理XML的方式: 1.1.6.1 Spring的Bean的屬性注入: 【構造方法的方式注入屬性】

【set方法的方式注入屬性】 1.1.6.2 Spring的屬性注入:物件型別的注入:

1.1.6.3 名稱空間p的屬性注入的方式:Spring2.x版本後提供的方式. 第一步:引入p名稱空間

第二步:使用p名稱空間. * 普通屬性: p:屬性名稱=”” * 物件型別屬性: p:屬性名稱-ref=””

<bean id="car2" class="cn.itcast.spring.demo4.Car2" p:name="寶馬7" p:price="1200000"/>
1.1.6.4 SpEL的方式的屬性注入:Spring3.x版本後提供的方式. SpEL:Spring Expression Language. 語法:#{ SpEL }
<!-- SpEL的注入的方式 -->
<bean id="car2" class="cn.itcast.spring.demo4.Car2">
	<property name="name" value="#{'賓士'}"/>
	<property name="price" value="#{800000}"/>
</bean>

<bean id="person" class="cn.itcast.spring.demo4.Person">
	<property name="name" value="#{'冠希'}"/>
	<property name="car2" value="#{car2}"/>
</bean>

<bean id="carInfo" class="cn.itcast.spring.demo4.CarInfo"></bean>

引用了另一個類的屬性
<bean id="car2" class="cn.itcast.spring.demo4.Car2">
	<property name="name" value="#{carInfo.carName}"/>
	<property name="price" value="#{carInfo.calculatePrice()}"/>
</bean>

1.1.6.5 注入複雜型別:

<bean id="collectionBean" class="cn.itcast.spring.demo5.CollectionBean">
	<!-- 陣列型別的屬性 -->
	<property name="arrs">
		<list>
			<value>會希</value>
			<value>冠希</value>
			<value>天一</value>
		</list>
	</property>
	
	<!-- 注入List集合的資料 -->
	<property name="list">
		<list>
			<value>芙蓉</value>
			<value>如花</value>
			<value>鳳姐</value>
		</list>
	</property>
	
	<!-- 注入Map集合 -->
	<property name="map">
		<map>
			<entry key="aaa" value="111"/>
			<entry key="bbb" value="222"/>
			<entry key="ccc" value="333"/>
		</map>
	</property>
	
	<!-- Properties的注入 -->
	<property name="properties">
		<props>
			<prop key="username">root</prop>
			<prop key="password">123</prop>
		</props>
	</property>
</bean>

1.1.6.6 Spring的分配置檔案的開發 一種:建立工廠的時候載入多個配置檔案: ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“applicationContext.xml”,“applicationContext2.xml”);

  • docs :API和開發規範.
  • libs :jar包和原始碼.
  • schema :約束. 1.1.7.2 步驟二:建立web專案,引入Spring的開發包:

在Spring的註解的AOP中需要引入spring-aop的jar包。 1.1.7.3 步驟三:引入相關配置檔案: log4j.properties applicationContext.xml 引入約束: spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html

  • 引入約束:(引入context的約束):
1.1.7.4 步驟四:編寫相關的類: public interface UserDao {
public void sayHello();

}

public class UserDaoImpl implements UserDao {

@Override
public void sayHello() {
	System.out.println("Hello Spring...");
}

} 1.1.7.5 步驟五:配置註解掃描

<context:component-scan base-package="com.itheima.spring.demo1"/>

1.1.7.6 在相關的類上添加註解: @Component(value=“userDao”) public class UserDaoImpl implements UserDao {

@Override
public void sayHello() {
	System.out.println("Hello Spring Annotation...");
}

} 1.1.7.7 編寫測試類: @Test public void demo2() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext( “applicationContext.xml”); UserDao userDao = (UserDao) applicationContext.getBean(“userDao”); userDao.sayHello(); }

1.1.8 Spring的Bean管理的中常用的註解: 1.1.8.1 @Component:元件.(作用在類上) Spring中提供@Component的三個衍生註解:(功能目前來講是一致的)

  • @Controller :WEB層
  • @Service :業務層
  • @Repository :持久層

這三個註解是為了讓標註類本身的用途清晰,Spring在後續版本會對其增強 1.1.8.2 屬性注入的註解:(使用註解注入的方式,可以不用提供set方法.) @Value :用於注入普通型別. @Autowired :自動裝配:

  • 預設按型別進行裝配.
  • 按名稱注入:
  • @Qualifier:強制使用名稱注入. @Resource相當於:
  • @Autowired和@Qualifier一起使用. 1.1.8.3 Bean的作用範圍的註解: @Scope:
  • singleton:單例
  • prototype:多例 1.1.8.4 Bean的生命週期的配置: @PostConstruct :相當於init-method @PreDestroy :相當於destroy-method 1.1.9 Spring的Bean管理的方式的比較:

XML和註解:

  • XML :結構清晰.
  • 註解 :開發方便.(屬性注入.)

實際開發中還有一種XML和註解整合開發:

  • Bean有XML配置.但是使用的屬性使用註解注入

Xml的屬性注入必須要依賴set方法,而用註解的方式可以不依賴set方法。.

1.1.10 AOP的概述 1.1.10.1 什麼是AOP

Spring是解決實際開發中的一些問題:

  • AOP解決OOP中遇到的一些問題.是OOP的延續和擴充套件. 1.1.10.2 為什麼學習AOP 對程式進行增強:不修改原始碼的情況下.
  • AOP可以進行許可權校驗,日誌記錄,效能監控,事務控制. 1.1.10.3 Spring的AOP的由來: AOP最早由AOP聯盟的組織提出的,制定了一套規範.Spring將AOP思想引入到框架中,必須遵守AOP聯盟的規範. 1.1.10.4 底層實現: 代理機制:
  • Spring的AOP的底層用到兩種代理機制:
    • JDK的動態代理 :針對實現了介面的類產生代理.針對帶有介面的實現類,底層動態代理產生的是jdk的動態代理類
    • Cglib的動態代理 :針對沒有實現介面的類產生代理. 應用的是底層的位元組碼增強的技術 生成當前類的子類物件.

1.1.11 Spring底層AOP的實現原理:(瞭解) 1.1.11.1 JDK動態代理增強一個類中方法: public class MyJDKProxy implements InvocationHandler {

private UserDao userDao;

public MyJDKProxy(UserDao userDao) {
	this.userDao = userDao;
}

// 編寫工具方法:生成代理:
public UserDao createProxy(){
	UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(),
			userDao.getClass().getInterfaces(), this);

	return userDaoProxy;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	if("save".equals(method.getName())){
		System.out.println("許可權校驗================");
	}
	return method.invoke(userDao, args);
}

} 1.1.11.2 Cglib動態代理增強一個類中的方法: public class MyCglibProxy implements MethodInterceptor{

private CustomerDao customerDao;

public MyCglibProxy(CustomerDao customerDao){
	this.customerDao = customerDao;
}
// 生成代理的方法:
public CustomerDao createProxy(){
	// 建立Cglib的核心類:
	Enhancer enhancer = new Enhancer();
	// 設定父類:
	enhancer.setSuperclass(CustomerDao.class);
	// 設定回撥:
	enhancer.setCallback(this);
	// 生成代理:
	CustomerDao customerDaoProxy = (CustomerDao) enhancer.create();
	return customerDaoProxy;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
	if("delete".equals(method.getName())){
		Object obj = methodProxy.invokeSuper(proxy, args);
		System.out.println("日誌記錄================");
		return obj;
	}
	
	return methodProxy.invokeSuper(proxy, args);
}

} 1.1.12 Spring的基於AspectJ的AOP開發 1.1.12.1 AOP的開發中的相關術語: Joinpoint(連線點):所謂連線點是指那些被攔截到的點。在spring中,這些點指的是方法,因為spring只支援方法型別的連線點.就是可以進行通知增強的那些方法。 Pointcut(切入點):所謂切入點是指我們要對那些Joinpoint進行增強的方法,是真正增強的方法。 Advice(通知/增強):所謂通知是指攔截到Joinpoint之後所要做的事情就是通知.通知分為前置通知,後置通知,異常通知,最終通知,環繞通知(切面要完成的功能),就是一個方法,可以切入到其他類的方法前後上。 Introduction(引介):引介是一種特殊的通知在不修改類程式碼的前提下, Introduction可以在執行期為類動態地新增一些方法或Field. Target(目標物件):代理的目標物件,就是需要增強的那些切入點方法的類。 Weaving(織入):是指把增強應用到目標物件來建立新的代理物件的過程.就是通知增強加入到切入點前後的過程。spring採用動態代理織入,而AspectJ採用編譯期織入和類裝在期織入 Proxy(代理):一個類被AOP織入增強後,就產生一個結果代理類 Aspect(切面): 裡面主要是方法,在通知這個方法上配置在哪個切入點進行使用, 是由多個通知和多個切入點組成的。 1.1.13 Spring使用AspectJ進行AOP的開發:XML的方式(*****) 1.1.13.1 引入相應的jar包

  • spring的傳統AOP的開發的包 spring-aop-4.2.4.RELEASE.jar com.springsource.org.aopalliance-1.0.0.jar
  • aspectJ的開發包: com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar spring-aspects-4.2.4.RELEASE.jar

1.1.13.2 引入Spring的配置檔案 引入AOP約束:

1.1.13.3 編寫目標類 建立介面和類: public interface OrderDao { public void save(); public void update(); public void delete(); public void find(); }

public class OrderDaoImpl implements OrderDao {

@Override
public void save() {
	System.out.println("儲存訂單...");
}

@Override
public void update() {
	System.out.println("修改訂單...");
}
@Override
public void delete() {
	System.out.println("刪除訂單...");
}
@Override
public void find() {
	System.out.println("查詢訂單...");
}

} 1.1.13.4 目標類的配置 1.1.13.5 整合Junit單元測試 就是為了減少每次都要用工廠建立物件的過程,直接用註解的方式,然後把直接這個物件當做測試類的屬性進行使用(前提要建立的物件必須已經在配置檔案中進行ioc,把建立物件的權利交給了Spring) 引入spring-test.jar

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(“classpath:applicationContext.xml”) public class SpringDemo3 { @Resource(name=“orderDao”) private OrderDao orderDao;

@Test
public void demo1(){
	orderDao.save();
	orderDao.update();
	orderDao.delete();
	orderDao.find();
}

} 1.1.13.6 通知型別 前置通知 :在目標方法執行之前執行. 後置通知 :在目標方法執行之後執行 環繞通知 :在目標方法執行前和執行後執行 異常丟擲通知:在目標方法執行出現 異常的時候 執行 最終通知 :無論目標方法是否出現異常 最終通知都會 執行. 1.1.13.7 切入點表示式 execution(表示式):就是用來簡化表示切入點的表示式,可以更好的對切入點進行表達使用 表示式: [方法訪問修飾符] 方法返回值 包名.類名.方法名(方法的引數) public * cn.itcast.spring.dao..(…)

  • cn.itcast.spring.dao..(…)
  • cn.itcast.spring.dao.UserDao+.*(…)
  • cn.itcast.spring.dao….(…)

1.1.13.8 編寫一個切面類 public class MyAspectXml { // 前置增強 public void before(){ System.out.println(“前置增強===========”); } } 1.1.13.9 配置完成增強

<!-- 進行aop的配置 -->
<aop:config>
	<!-- 配置切入點表示式:哪些類的哪些方法需要進行增強 -->
	<aop:pointcut expression="execution(* cn.itcast.spring.demo3.OrderDao.save(..))" id="pointcut1"/>
	<!—切面:配置通知,就是在哪些切入點加入什麼增強方法 -->
	<aop:aspect ref="myAspectXml">
		<aop:before method="before" pointcut-ref="pointcut1"/>
	</aop:aspect>
</aop:config>

1.1.13.10 其他的增強的配置:

<!-- 進行aop的配置 -->
<aop:config>
	<!-- 配置切入點表示式:哪些類的哪些方法需要進行增強 -->
	<aop:pointcut expression="execution(* cn.itcast.spring.demo3.*Dao.save(..))" id="pointcut1"/>
	<aop:pointcut expression="execution(* cn.itcast.spring.demo3.*Dao.delete(..))" id="pointcut2"/>
	<aop:pointcut expression="execution(* cn.itcast.spring.demo3.*Dao.update(..))" id="pointcut3"/>
	<aop:pointcut expression="execution(* cn.itcast.spring.demo3.*Dao.find(..))" id="pointcut4"/>
	<!-- 配置切面 -->
	<aop:aspect ref="myAspectXml">
		<aop:before method="before" pointcut-ref="pointcut1"/>
		<aop:after-returning method="afterReturing" pointcut-ref="pointcut2"/>
		<aop:around method="around" pointcut-ref="pointcut3"/>
		<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4"/>
		<aop:after method="after" pointcut-ref="pointcut4"/>
	</aop:aspect>
</aop:config>

1.1.14 Spring使用AspectJ進行AOP的開發:註解的方式 1.1.14.1 引入相關的jar包:

  • spring的傳統AOP的開發的包 spring-aop-4.2.4.RELEASE.jar com.springsource.org.aopalliance-1.0.0.jar
  • aspectJ的開發包: com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar spring-aspects-4.2.4.RELEASE.jar

1.1.14.2 引入Spring的配置檔案 引入AOP約束:

1.1.14.3 編寫目標類: public class ProductDao { public void save(){ System.out.println("儲存商品..."); } public void update(){ System.out.println("修改商品..."); } public void delete(){ System.out.println("刪除商品..."); } public void find(){ System.out.println("查詢商品..."); } } 1.1.14.4 配置目標類: 1.1.14.5 開啟aop註解的自動代理: 1.1.14.6 AspectJ的AOP的註解: @Aspect:定義切面類的註解

通知型別: * @Before :前置通知 * @AfterReturing :後置通知 * @Around :環繞通知 * @After :最終通知 * @AfterThrowing :異常丟擲通知.

@Pointcut:定義切入點的註解 1.1.14.7 編寫切面類: @Aspect public class MyAspectAnno {

@Before("MyAspectAnno.pointcut1()")
public void before(){
	System.out.println("前置通知===========");
}

@Pointcut("execution(* cn.itcast.spring.demo4.ProductDao.save(..))")
private void pointcut1(){}

} 1.1.14.8 配置切面: 1.1.14.9 其他通知的註解: @Aspect public class MyAspectAnno {

@Before("MyAspectAnno.pointcut1()")
public void before(){
	System.out.println("前置通知===========");
}

@AfterReturning("MyAspectAnno.pointcut2()")
public void afterReturning(){
	System.out.println("後置通知===========");
}

@Around("MyAspectAnno.pointcut3()")

//環繞通知的話必須傳入這個連結點引數 public Object around(ProceedingJoinPoint joinPoint) throws Throwable{ //在切入點前進行操作 System.out.println(“環繞前通知==========”); //這個代表執行切入點這個方法 Object obj = joinPoint.proceed(); //在切入後前進行操作 System.out.println(“環繞後通知==========”); return obj; } @AfterThrowing(“MyAspectAnno.pointcut4()”) public void afterThrowing(){ System.out.println(“異常丟擲通知========”); } @After(“MyAspectAnno.pointcut4()”) public void after(){ System.out.println(“最終通知==========”); }

//配置切入點,就是指明那個那個類裡面的那個方法是切入點,方便使用,直接用 切面類.切面的方法名就可以代表那個切入點了。 @Pointcut(“execution(* cn.itcast.spring.demo4.ProductDao.save(…))”) private void pointcut1(){} @Pointcut(“execution(* cn.itcast.spring.demo4.ProductDao.update(…))”) private void pointcut2(){} @Pointcut(“execution(* cn.itcast.spring.demo4.ProductDao.delete(…))”) private void pointcut3(){} @Pointcut(“execution(* cn.itcast.spring.demo4.ProductDao.find(…))”) private void pointcut4(){} } 1.1.15 Spring的JDBC的模板: 1.1.15.1 Spring提供了很多持久層技術的模板類簡化程式設計:

1.1.15.2 建立資料庫和表:

1.1.15.3 引入相關開發包: Spring的基本的開發包需要引入的:6個.

1.1.15.4 建立一個測試類: @Test // JDBC模板的基本使用: public void demo1(){ DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(“com.mysql.jdbc.Driver”); dataSource.setUrl(“jdbc:mysql:///spring_day03”); dataSource.setUsername(“root”); dataSource.setPassword(“123”);

	JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
	jdbcTemplate.update("insert into account values (null,?,?)", "會希",10000d);
}

1.1.16 將連線池的配置交給Spring管理: 1.1.16.1 Spring內建的連線池的配置: 【引入Spring的配置檔案】

【配置內建連線池】 【將模板配置到Spring中】 【編寫測試類】 **** 引入spring-aop.jar

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(“classpath:applicationContext.xml”) public class SpringDemo2 {

@Resource(name="jdbcTemplate")
private JdbcTemplate jdbcTemplate;

@Test
public void demo1(){
	jdbcTemplate.update("insert into account values (null,?,?)", "鳳姐",10000d);
}

} 1.1.16.2 Spring中配置DBCP連線池: 【引入dbcp連線池的jar包】

【配置連線池】 1.1.16.3 配置c3p0連線池: 【引入相應的jar包】 com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar

【配置連線池】 1.1.17 JDBC模板的CRUD的操作: 1.1.17.1 JDBC模板CRUD的操作: @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(“classpath:applicationContext.xml”) public class SpringDemo3 {

@Resource(name="jdbcTemplate")
private JdbcTemplate jdbcTemplate;

@Test
// 插入操作
public void demo1(){
	jdbcTemplate.update("insert into account values (null,?,?)", "冠希",10000d);
}

@Test
// 修改操作
public void demo2(){
	jdbcTemplate.update("update account set name=?,money =? where id = ?", "思雨",10000d,5);
}

@Test
// 刪除操作
public void demo3(){
	jdbcTemplate.update("delete from account where id = ?", 5);
}

@Test
// 查詢一條記錄
public void demo4(){
	Account account = jdbcTemplate.queryForObject("select * from account where id = ?", new MyRowMapper(), 1);
	System.out.println(account);
}

@Test
// 查詢所有記錄
public void demo5(){
	List<Account> list = jdbcTemplate.query("select * from account", new MyRowMapper());
	for (Account account : list) {
		System.out.println(account);
	}
}

class MyRowMapper implements RowMapper<Account>{

	@Override
	public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
		Account account = new Account();
		account.setId(rs.getInt("id"));
		account.setName(rs.getString("name"));
		account.setMoney(rs.getDouble("money"));
		return account;
	}
	
}

}

1.2 Spring的事務管理 1.2.1 事務的回顧 1.2.1.1 什麼事務  事務:邏輯上的一組操作,組成這組操作的各個單元,要麼全都成功,要麼全都失敗。 1.2.1.2 事務的特性  原子性:事務不可分割  一致性:事務執行前後資料完整性保持一致  隔離性:一個事務的執行不應該受到其他事務的干擾  永續性:一旦事務結束,資料就持久化到資料庫 1.2.1.3 如果不考慮隔離性引發安全性問題  讀問題  髒讀 :一個事務讀到另一個事務未提交的資料  不可重複讀 :一個事務讀到另一個事務已經提交的update的資料,導致一個事務中多次查詢結果不一致  虛讀、幻讀 :一個事務讀到另一個事務已經提交的insert的資料,導致一個事務中多次查詢結果不一致。  寫問題  丟失更新 1.2.1.4 解決讀問題  設定事務的隔離級別  Read uncommitted :未提交讀,任何讀問題解決不了。  Read committed :已提交讀,解決髒讀,但是不可重複讀和虛讀有可能發生。  Repeatable read :重複讀,解決髒讀和不可重複讀,但是虛讀有可能發生。  Serializable :解決所有讀問題。 1.2.2 Spring的事務管理的API 1.2.2.1 PlatformTransactionManager:平臺事務管理器  平臺事務管理器:介面,是Spring用於管理事務的真正的物件。  DataSourceTransactionManager :底層使用JDBC管理事務  HibernateTransactionManager :底層使用Hibernate管理事務 1.2.2.2 TransactionDefinition :事務定義資訊  事務定義:用於定義事務的相關的資訊,隔離級別、超時資訊、傳播行為、是否只讀 1.2.2.3 TransactionStatus:事務的狀態  事務狀態:用於記錄在事務管理過程中,事務的狀態的物件。 1.2.2.4 事務管理的API的關係: Spring進行事務管理的時候,首先平臺事務管理器根據事務定義資訊進行事務的管理,在事務管理過程中,產生各種狀態,將這些狀態的資訊記錄到事務狀態的物件中。 1.2.3 Spring的事務的傳播行為 1.2.3.1 Spring的傳播行為  Spring中提供了七種事務的傳播行為:  保證多個操作在同一個事務中  PROPAGATION_REQUIRED :預設值,如果A中有事務,使用A中的事務,如果A沒有,建立一個新的事務,將操作包含進來  PROPAGATION_SUPPORTS :支援事務,如果A中有事務,使用A中的事務。如果A沒有事務,不使用事務。  PROPAGATION_MANDATORY :如果A中有事務,使用A中的事務。如果A沒有事務,丟擲異常。

 保證多個操作不在同一個事務中  PROPAGATION_REQUIRES_NEW :如果A中有事務,將A的事務掛起(暫停),建立新事務,只包含自身操作。如果A中沒有事務,建立一個新事務,包含自身操作。  PROPAGATION_NOT_SUPPORTED :如果A中有事務,將A的事務掛起。不使用事務管理。  PROPAGATION_NEVER :如果A中有事務,報異常。

 巢狀式事務  PROPAGATION_NESTED :巢狀事務,如果A中有事務,按照A的事務執行,執行完成後,設定一個儲存點,執行B中的操作,如果沒有異常,執行通過,如果有異常,可以選擇回滾到最初始位置,也可以回滾到儲存點。 1.2.4 Spring的事務管理 1.2.4.1 搭建Spring的事務管理的環境  建立Service的介面和實現類

 建立DAO的介面和實現類

 配置Service和DAO:交給Spring管理

 在DAO中編寫扣錢和加錢方法:  配置連線池和JDBC的模板

 在DAO注入Jdbc的模板:

 測試

1.2.5 Spring的事務管理:一類:程式設計式事務(需要手動編寫程式碼)–瞭解 1.2.5.1 第一步:配置平臺事務管理器

1.2.5.2 第二步:Spring提供了事務管理的模板類  配置事務的管理的模板類

1.2.5.3 第三步:在業務層注入事務管理的模板

1.2.5.4 編寫事務管理的程式碼

1.2.5.5 測試:

1.2.6 Spring的事務管理:二類:宣告式事務管理(通過配置實現)—AOP 1.2.6.1 XML方式的宣告式事務管理  第一步:引入aop的開發包  第二步:恢復轉賬環境  第三步:配置事務管理器

 第四步:配置增強

 第五步:AOP的配置

 測試

1.2.6.2 註解方式的宣告式事務管理  第一步:引入aop的開發包  第二步:恢復轉賬環境  第三步:配置事務管理器

 第四步:開啟註解事務

 第五步:在業務層添加註解