SSH框架之Spring第四篇

  • 2019 年 10 月 6 日
  • 筆記

版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。

本文鏈接:https://blog.csdn.net/zhao1299002788/article/details/101168019

1.1 JdbcTemplate概述 :  		它是spring框架中提供的一個對象,是對原始JdbcAPI對象的簡單封裝.spring框架為我們提供了很多的操作模板類.  		ORM持久化技術						模板類  		JDBC					org.springframework.jdbc.core.JdbcTemplate.  		Hibernate3.0 			org.springframework.orm.hibernate3.HibernateTemplate.  		IBatis(MyBatis)			org.springframework.orm.ibatis.SqlMapClientTemplate.  		JPA						org.springframework.orm.jpa.JpaTemplate.  	在導包的時候需要導入spring-jdbc-4.24.RELEASF.jar,還需要導入一個spring-tx-4.2.4.RELEASE.jar(它和事務有關)    	<!-- 配置數據源 -->  		<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">  			<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>  			<property name="url" value="jdbc:mysql:// /spring_day04"></property>  			<property name="username" value="root"></property>  			<property name="password" value="1234"></property>  		</bean>  	1.3.3.3配置spring內置數據源  		spring框架也提供了一個內置數據源,我們也可以使用spring的內置數據源,它就在spring-jdbc-4.2.4.REEASE.jar包中:  		<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  			<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>  			<property name="url" value="jdbc:mysql:///spring_day04"></property>  			<property name="username" value="root"></property>  			<property name="password" value="1234"></property>  		</bean>  	1.3.4將資料庫連接的資訊配置到屬性文件中:  		【定義屬性文件】  		jdbc.driverClass=com.mysql.jdbc.Driver  		jdbc.url=jdbc:mysql:///spring_day02  		jdbc.username=root  		jdbc.password=123  		【引入外部的屬性文件】  		一種方式:  			<!-- 引入外部屬性文件: -->  			<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  				<property name="location" value="classpath:jdbc.properties"/>  			</bean>    		二種方式:  		<context:property-placeholder location="classpath:jdbc.properties"/>    	1.4JdbcTemplate的增刪改查操作  		1.4.1前期準備  		創建資料庫:  		create database spring_day04;  		use spring_day04;  		創建表:  		create table account(  			id int primary key auto_increment,  			name varchar(40),  			money float  		)character set utf8 collate utf8_general_ci;  	1.4.2在spring配置文件中配置JdbcTemplate  		<?xml version="1.0" encoding="UTF-8"?>  		<beans xmlns="http://www.springframework.org/schema/beans"  				xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  				xsi:schemaLocation="http://www.springframework.org/schema/beans  				http://www.springframework.org/schema/beans/spring-beans.xsd">    			<!-- 配置一個資料庫的操作模板:JdbcTemplate -->  			<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  				<property name="dataSource" ref="dataSource"></property>  			</bean>    			<!-- 配置數據源 -->  			<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  			<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>  			<property name="url" value="jdbc:mysql:///spring_day04"></property>  			<property name="username" value="root"></property>  			<property name="password" value="1234"></property>  		</bean>  		</beans>  	1.4.3最基本使用  		public class JdbcTemplateDemo2 {  			public static void main(String[] args) {  				//1.獲取Spring容器  				ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");  				//2.根據id獲取bean對象  				JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");  				//3.執行操作  				jt.execute("insert into account(name,money)values('eee',500)");  			}  		}  	1.4.4保存操作  		public class JdbcTemplateDemo3 {  			public static void main(String[] args) {    				//1.獲取Spring容器  				ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");  				//2.根據id獲取bean對象  				JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");  				//3.執行操作  				//保存  				jt.update("insert into account(name,money)values(?,?)","fff",5000);  			}  		}  	1.4.5更新操作  		public class JdbcTemplateDemo3 {  			public static void main(String[] args) {    				//1.獲取Spring容器  				ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");  				//2.根據id獲取bean對象  				JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");  				//3.執行操作  				//修改  				jt.update("update account set money = money-? where id = ?",300,6);  			}  		}  	1.4.6刪除操作  		public class JdbcTemplateDemo3 {  			public static void main(String[] args) {    				//1.獲取Spring容器  				ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");  				//2.根據id獲取bean對象  				JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");  				//3.執行操作  				//刪除  				jt.update("delete from account where id = ?",6);  			}  		}  	1.4.7查詢所有操作  		public class JdbcTemplateDemo3 {  			public static void main(String[] args) {    				//1.獲取Spring容器  				ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");  				//2.根據id獲取bean對象  				JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");  				//3.執行操作  				//查詢所有  				List<Account> accounts = jt.query("select * from account where money > ? ",  													new AccountRowMapper(), 500);  				for(Account o : accounts){  					System.out.println(o);  				}  			}  		}    		public class AccountRowMapper 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.getFloat("money"));  				return account;  			}    		}    	1.4.8查詢一個操作  		使用RowMapper的方式:常用的方式  		public class JdbcTemplateDemo3 {  			public static void main(String[] args) {    				//1.獲取Spring容器  				ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");  				//2.根據id獲取bean對象  				JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");  				//3.執行操作  				//查詢一個  				List<Account> as = jt.query("select * from account where id = ? ",  												new AccountRowMapper(), 55);  				System.out.println(as.isEmpty()?"沒有結果":as.get(0));  			}  		}  	1.4.9查詢返回一行一列操作  		public class JdbcTemplateDemo3 {  			public static void main(String[] args) {    				//1.獲取Spring容器  				ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");  				//2.根據id獲取bean對象  				JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");  				//3.執行操作  				//查詢返回一行一列:使用聚合函數,在不使用group by字句時,都是返回一行一列。最長用的就是分頁中獲取總記錄條數  				Integer total = jt.queryForObject("select count(*) from account where money > ? ",Integer.class,500);  				System.out.println(total);  			}  		}  applicationContext.xml  		<?xml version="1.0" encoding="UTF-8"?>  		<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">    			<!-- 使用Spring管理連接池對象,Spring內置的連接池對象 -->    			<!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  				<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>  				<property name="url" value="jdbc:mysql:///spring_04"/>  				<property name="username" value="root"></property>  				<property name="password" value="root"></property>  			</bean> -->    			<!-- 配置數據源,使用Spring整合dbcp連接,沒有導入jar包 -->  			<!-- <bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">  				<property name="driverClassName" value="com.mysql.jdbc.Driver"/>  				<property name="url" value="jdbc:mysql:///spring_04"/>  				<property name="username" value="root"/>  				<property name="password" value="root"/>  			</bean> -->    			<!-- 使用Spring整合c3p0的連接池,沒有採用屬性文件的方式 -->  			<!--  			<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">  				<property name="driverClass" value="com.mysql.jdbc.Driver"/>  				<property name="jdbcUrl" value="jdbc:mysql:///spring_04"/>  				<property name="user" value="root"/>  				<property name="password" value="root"/>  			</bean> -->    			<!-- 使用context:property-placeholder標籤,讀取屬性文件 -->  			<context:property-placeholder location="classpath:db.properties"/>    			<!-- 使用Spring整合c3p0的連接池,採用屬性文件的方式 -->  			<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">  				<property name="driverClass" value="${jdbc.driver}"/>  				<property name="jdbcUrl" value="${jdbc.url}"/>  				<property name="user" value="${jdbc.user}"/>  				<property name="password" value="${jdbc.password}"/>    			</bean>  			<!-- spring管理JbdcTemplate模板 -->  			<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  				<property name="dataSource" ref="dataSource"/>  			</bean>    		</beans>  db.properties : 屬性文件  		jdbc.driver=com.mysql.jdbc.Driver  		jdbc.url=jdbc:mysql:///spring_day04  		jdbc.user=root  		jdbc.password=root  Demo測試 :  	package com.ithiema.demo1;    	import java.sql.ResultSet;  	import java.sql.SQLException;  	import java.util.List;    	import javax.annotation.Resource;    	import org.junit.Test;  	import org.junit.runner.RunWith;  	import org.springframework.jdbc.core.JdbcTemplate;  	import org.springframework.jdbc.core.RowMapper;  	import org.springframework.test.context.ContextConfiguration;  	import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;    	/**  	 * Spring整合JdbcTemplate的方式入門  	 * @author Administrator  	 */  	@RunWith(SpringJUnit4ClassRunner.class)  	@ContextConfiguration("classpath:applicationContext.xml")  	public class Demo11 {    		@Resource(name="jdbcTemplate")  		private JdbcTemplate jdbcTemplate;    		/**  		 * 添加  		 */  		@Test  		public void run1(){  			jdbcTemplate.update("insert into account values (null,?,?)", "嘿嘿",10000);  		}    		/**  		 * 修改  		 */  		@Test  		public void run2(){  			jdbcTemplate.update("update account set name = ?,money = ? where id = ?", "嘻嘻",5000,6);  		}    		/**  		 * 刪除  		 */  		@Test  		public void run3(){  			jdbcTemplate.update("delete from account where id = ?", 6);  		}    		/**  		 * 查詢多條數據  		 */  		@Test  		public void run4(){  			// sql  		sql語句  			// rowMapper	提供封裝數據的介面,自己提供實現類(自己封裝數據的)  			List<Account> list = jdbcTemplate.query("select * from account", new BeanMapper());  			for (Account account : list) {  				System.out.println(account);  			}  		}  	}    	/**  	 * 自己封裝的實現類,封裝數據的  	 * @author Administrator  	 */  	class BeanMapper implements RowMapper<Account>{    		/**  		 * 一行一行封裝數據的  		 */  		public Account mapRow(ResultSet rs, int index) throws SQLException {  			// 創建Account對象,一個屬性一個屬性賦值,返回對象  			Account ac = new Account();  			ac.setId(rs.getInt("id"));  			ac.setName(rs.getString("name"));  			ac.setMoney(rs.getDouble("money"));  			return ac;  		}    	}    2,1 Spring 事務控制我們要明確的  	1: JavaEE體系進行分層開發,事務處理位於業務層,Spring提供了分層設計業務層的事務處理解決方案.  	2: Spring框架為我們提供就一組事務控制的介面.這組介面是在spring-tx-4.2.4RELEASE.jar中.  	3: spring的事務都是基於AOP的,它既可以使用編程的方式實現,也可以使用配置的方式實現  	2.2Spring中事務控制的API介紹  		2.2.1PlatformTransactionManager  		此介面是spring的事務管理器,它裡面提供了我們常用的操作事務的方法,如下圖:    		我們在開發中都是使用它的實現類,如下圖:    		真正管理事務的對象  		org.springframework.jdbc.datasource.DataSourceTransactionManager	使用Spring JDBC或iBatis 進行持久化數據時使用  		org.springframework.orm.hibernate3.HibernateTransactionManager		使用Hibernate版本進行持久化數據時使用  	2.2.2TransactionDefinition  		它是事務的定義資訊對象,裡面有如下方法:    	2.2.2.1事務的隔離級別    	2.2.2.2事務的傳播行為  		REQUIRED:如果當前沒有事務,就新建一個事務,如果已經存在一個事務中,加入到這個事務中。一般的選擇(默認值)  		SUPPORTS:支援當前事務,如果當前沒有事務,就以非事務方式執行(沒有事務)  		MANDATORY:使用當前的事務,如果當前沒有事務,就拋出異常  		REQUERS_NEW:新建事務,如果當前在事務中,把當前事務掛起。  		NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起  		NEVER:以非事務方式運行,如果當前存在事務,拋出異常  		NESTED:如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行REQUIRED類似的操作。  		2.2.2.3超時時間  		默認值是-1,沒有超時限制。如果有,以秒為單位進行設置。  		2.2.2.4是否是只讀事務  		建議查詢時設置為只讀。  		2.2.3TransactionStatus  		此介面提供的是事務具體的運行狀態,方法介紹如下圖:    	2.3基於XML的聲明式事務控制(配置方式)重點  		2.3.1環境搭建  		2.3.1.1第一步:拷貝必要的jar包到工程的lib目錄    	2.3.1.2第二步:創建spring的配置文件並導入約束  		<?xml version="1.0" encoding="UTF-8"?>  		<beans xmlns="http://www.springframework.org/schema/beans"  				xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  				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/tx  						http://www.springframework.org/schema/tx/spring-tx.xsd  						http://www.springframework.org/schema/aop  						http://www.springframework.org/schema/aop/spring-aop.xsd">  		</beans>  		2.3.1.3第三步:準備資料庫表和實體類  		創建資料庫:  		create database spring_day04;  		use spring_day04;  		創建表:  		create table account(  			id int primary key auto_increment,  			name varchar(40),  			money float  		)character set utf8 collate utf8_general_ci;  		/**  		 * 賬戶的實體  		 */  		public class Account implements Serializable {    			private Integer id;  			private String name;  			private Float money;  			public Integer getId() {  				return id;  			}  			public void setId(Integer id) {  				this.id = id;  			}  			public String getName() {  				return name;  			}  			public void setName(String name) {  				this.name = name;  			}  			public Float getMoney() {  				return money;  			}  			public void setMoney(Float money) {  				this.money = money;  			}  			@Override  			public String toString() {  				return "Account [id=" + id + ", name=" + name + ", money=" + money + "]";  			}  		}  		2.3.1.4第四步:編寫業務層介面和實現類  		/**  		 * 賬戶的業務層介面  		 */  		public interface IAccountService {    			/**  			 * 根據id查詢賬戶資訊  			 * @param id  			 * @return  			 */  			Account findAccountById(Integer id);//查    			/**  			 * 轉賬  			 * @param sourceName	轉出賬戶名稱  			 * @param targeName		轉入賬戶名稱  			 * @param money			轉賬金額  			 */  			void transfer(String sourceName,String targeName,Float money);//增刪改  		}    		/**  		 * 賬戶的業務層實現類  		 */  		public class AccountServiceImpl implements IAccountService {    			private IAccountDao accountDao;    			public void setAccountDao(IAccountDao accountDao) {  				this.accountDao = accountDao;  			}    			@Override  			public Account findAccountById(Integer id) {  				return accountDao.findAccountById(id);  			}    			@Override  			public void transfer(String sourceName, String targeName, Float money) {  				//1.根據名稱查詢兩個賬戶  				Account source = accountDao.findAccountByName(sourceName);  				Account target = accountDao.findAccountByName(targeName);  				//2.修改兩個賬戶的金額  				source.setMoney(source.getMoney()-money);//轉出賬戶減錢  				target.setMoney(target.getMoney()+money);//轉入賬戶加錢  				//3.更新兩個賬戶  				accountDao.updateAccount(source);  				int i=1/0;  				accountDao.updateAccount(target);  			}  		}  		2.3.1.5第五步:編寫Dao介面和實現類  		/**  		 * 賬戶的持久層介面  		 */  		public interface IAccountDao {    			/**  			 * 根據id查詢賬戶資訊  			 * @param id  			 * @return  			 */  			Account findAccountById(Integer id);    			/**  			 * 根據名稱查詢賬戶資訊  			 * @return  			 */  			Account findAccountByName(String name);    			/**  			 * 更新賬戶資訊  			 * @param account  			 */  			void updateAccount(Account account);  		}  		/**  		 * 賬戶的持久層實現類  		 * 此版本dao,只需要給它的父類注入一個數據源  		 */  		public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {    			@Override  			public Account findAccountById(Integer id) {  				List<Account> list = getJdbcTemplate().query("select * from account where id = ? ",new AccountRowMapper(),id);  				return list.isEmpty()?null:list.get(0);  			}    			@Override  			public Account findAccountByName(String name) {  				List<Account> list =  getJdbcTemplate().query("select * from account where name = ? ",new AccountRowMapper(),name);  				if(list.isEmpty()){  					return null;  				}  				if(list.size()>1){  					throw new RuntimeException("結果集不唯一,不是只有一個賬戶對象");  				}  				return list.get(0);  			}    			@Override  			public void updateAccount(Account account) {  				getJdbcTemplate().update("update account set money = ? where id = ? ",account.getMoney(),account.getId());  			}  		}    		/**  		 * 賬戶的封裝類RowMapper的實現類  		 */  		public class AccountRowMapper 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.getFloat("money"));  				return account;  			}  		}  		2.3.1.6第六步:在配置文件中配置業務層和持久層對  		<!-- 配置service -->  		<bean id="accountService" class="com.baidu.service.impl.AccountServiceImpl">  			<property name="accountDao" ref="accountDao"></property>  		</bean>    		<!-- 配置dao -->  		<bean id="accountDao" class="com.baidu.dao.impl.AccountDaoImpl">  			<!-- 注入dataSource -->  			<property name="dataSource" ref="dataSource"></property>  		</bean>    		<!-- 配置數據源 -->  		<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  			<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>  			<property name="url" value="jdbc:mysql:///spring_day04"></property>  			<property name="username" value="root"></property>  			<property name="password" value="1234"></property>  		</bean>  	2.3.2配置步驟  		2.3.2.1第一步:配置事務管理器  		<!-- 配置一個事務管理器 -->  		<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  			<!-- 注入DataSource -->  			<property name="dataSource" ref="dataSource"></property>  		</bean>  		2.3.2.2第二步:配置事務的通知引用事務管理器  		<!-- 事務的配置 -->  		<tx:advice id="txAdvice" transaction-manager="transactionManager">  		</tx:advice>  		2.3.2.3第三步:配置事務的屬性  		<!--在tx:advice標籤內部 配置事務的屬性 -->  		<tx:attributes>  		<!-- 指定方法名稱:是業務核心方法  			read-only:是否是只讀事務。默認false,不只讀。  			isolation:指定事務的隔離級別。默認值是使用資料庫的默認隔離級別。  			propagation:指定事務的傳播行為。  			timeout:指定超時時間。默認值為:-1。永不超時。  			rollback-for:用於指定一個異常,當執行產生該異常時,事務回滾。產生其他異常,事務不回滾。沒有默認值,任何異常都回滾。  			no-rollback-for:用於指定一個異常,當產生該異常時,事務不回滾,產生其他異常時,事務回滾。沒有默認值,任何異常都回滾。  			-->  			<tx:method name="*" read-only="false" propagation="REQUIRED"/>  			<tx:method name="find*" read-only="true" propagation="SUPPORTS"/>  		</tx:attributes>  		2.3.2.4第四步:配置AOP-切入點表達式  		<!-- 配置aop -->  		<aop:config>  			<!-- 配置切入點表達式 -->  			<aop:pointcut expression="execution(* com.baidu.service.impl.*.*(..))" id="pt1"/>  		</aop:config>  		2.3.2.5第五步:配置切入點表達式和事務通知的對應關係  		<!-- 在aop:config標籤內部:建立事務的通知和切入點表達式的關係 -->  		<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>  		2.4基於XML和註解組合使用的整合方式  		2.4.1環境搭建  		2.4.1.1第一步:拷貝必備的jar包到工程的lib目錄    		2.4.1.2第二步:創建spring的配置文件導入約束並配置掃描的包  		<?xml version="1.0" encoding="UTF-8"?>  		<beans xmlns="http://www.springframework.org/schema/beans"  					xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  					xmlns:aop="http://www.springframework.org/schema/aop"  					xmlns:tx="http://www.springframework.org/schema/tx"  					xmlns:context="http://www.springframework.org/schema/context"  					xsi:schemaLocation="http://www.springframework.org/schema/beans  						http://www.springframework.org/schema/beans/spring-beans.xsd  							http://www.springframework.org/schema/tx  							http://www.springframework.org/schema/tx/spring-tx.xsd  							http://www.springframework.org/schema/aop  							http://www.springframework.org/schema/aop/spring-aop.xsd  							http://www.springframework.org/schema/context  						http://www.springframework.org/schema/context/spring-context.xsd">  			<!-- 配置spring要掃描的包 -->  			<context:component-scan base-package="com.baidu"></context:component-scan>  		</beans>  	2.4.1.3第三步:創建資料庫表和實體類  		和基於xml的配置相同。  		2.4.1.4第四步:創建業務層介面和實現類並使用註解讓spring管理  		業務層介面和基於xml配置的時候相同。略    		/**  		 * 賬戶的業務層實現類  		 */  		@Service("accountService")  		public class AccountServiceImpl implements IAccountService {  			@Autowired  			private IAccountDao accountDao;    			@Override  			public Account findAccountById(Integer id) {  				return accountDao.findAccountById(id);  			}    			@Override  			public void transfer(String sourceName, String targeName, Float money) {  				//1.根據名稱查詢兩個賬戶  				Account source = accountDao.findAccountByName(sourceName);  				Account target = accountDao.findAccountByName(targeName);  				//2.修改兩個賬戶的金額  				source.setMoney(source.getMoney()-money);//轉出賬戶減錢  				target.setMoney(target.getMoney()+money);//轉入賬戶加錢  				//3.更新兩個賬戶  				accountDao.updateAccount(source);  				int i=1/0;  				accountDao.updateAccount(target);  			}  		}  	2.4.1.5第五步:創建Dao介面和實現類並使用註解讓spring管理  		Dao層介面和AccountRowMapper與基於xml配置的時候相同。略    		@Repository("accountDao")  		public class AccountDaoImpl implements IAccountDao {    			@Autowired  			private JdbcTemplate jdbcTemplate;    			@Override  			public Account findAccountById(Integer id) {  				List<Account> list = jdbcTemplate.query("select * from account where id = ? ",new AccountRowMapper(),id);  				return list.isEmpty()?null:list.get(0);  			}    			@Override  			public Account findAccountByName(String name) {  				List<Account> list =  jdbcTemplate.query("select * from account where name = ? ",new AccountRowMapper(),name);  				if(list.isEmpty()){  					return null;  				}  				if(list.size()>1){  					throw new RuntimeException("結果集不唯一,不是只有一個賬戶對象");  				}  				return list.get(0);  			}    			@Override  			public void updateAccount(Account account) {  				jdbcTemplate.update("update account set money = ? where id = ? ",account.getMoney(),account.getId());  			}  		}  	2.4.2配置步驟  		2.4.2.1第一步:配置數據源和JdbcTemplate  		<!-- 配置數據源 -->  		<bean id="dataSource"  					class="org.springframework.jdbc.datasource.DriverManagerDataSource">  			<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>  			<property name="url" value="jdbc:mysql:///spring_day04"></property>  			<property name="username" value="root"></property>  			<property name="password" value="1234"></property>  		</bean>      	2.4.2.2第二步:配置事務管理器並注入數據源  		<!-- 配置JdbcTemplate -->  		<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  			<property name="dataSource" ref="dataSource"></property>  		</bean>  	2.4.2.3第三步:在業務層使用@Transactional註解  		@Service("accountService")  		@Transactional(readOnly=true,propagation=Propagation.SUPPORTS)  		public class AccountServiceImpl implements IAccountService {    			@Autowired  			private IAccountDao accountDao;    			@Override  			public Account findAccountById(Integer id) {  				return accountDao.findAccountById(id);  			}    			@Override  			@Transactional(readOnly=false,propagation=Propagation.REQUIRED)  			public void transfer(String sourceName, String targeName, Float money) {  				//1.根據名稱查詢兩個賬戶  				Account source = accountDao.findAccountByName(sourceName);  				Account target = accountDao.findAccountByName(targeName);  				//2.修改兩個賬戶的金額  				source.setMoney(source.getMoney()-money);//轉出賬戶減錢  				target.setMoney(target.getMoney()+money);//轉入賬戶加錢  				//3.更新兩個賬戶  				accountDao.updateAccount(source);  				//int i=1/0;  				accountDao.updateAccount(target);  			}  		}    		該註解的屬性和xml中的屬性含義一致。該註解可以出現在介面上,類上和方法上。  		出現介面上,表示該介面的所有實現類都有事務支援。  		出現在類上,表示類中所有方法有事務支援  		出現在方法上,表示方法有事務支援。  		以上三個位置的優先順序:方法>類>介面  	2.4.2.4第四步:在配置文件中開啟spring對註解事務的支援  		<!-- 開啟spring對註解事務的支援 -->  		<tx:annotation-driven transaction-manager="transactionManager"/>  		2.5基於純註解的聲明式事務控制(配置方式)重點  		2.5.1環境搭建  		2.5.1.1第一步:拷貝必備的jar包到工程的lib目錄    		2.5.1.2第二步:創建一個類用於載入spring的配置並指定要掃描的包  		/**  		 * 用於初始化spring容器的配置類  		 */  		@Configuration  		@ComponentScan(basePackages="com.baidu")  		public class SpringConfiguration {    		}      2.5.1.3第三步:創建資料庫表和實體類  		和基於xml的配置相同。略  	2.5.1.4第四步:創建業務層介面和實現類並使用註解讓spring管理  		業務層介面和基於xml配置的時候相同。略    		/**  		 * 賬戶的業務層實現類  		 */  		@Service("accountService")  		public class AccountServiceImpl implements IAccountService {  			@Autowired  			private IAccountDao accountDao;    			@Override  			public Account findAccountById(Integer id) {  				return accountDao.findAccountById(id);  			}    			@Override  			public void transfer(String sourceName, String targeName, Float money) {  				//1.根據名稱查詢兩個賬戶  				Account source = accountDao.findAccountByName(sourceName);  				Account target = accountDao.findAccountByName(targeName);  				//2.修改兩個賬戶的金額  				source.setMoney(source.getMoney()-money);//轉出賬戶減錢  				target.setMoney(target.getMoney()+money);//轉入賬戶加錢  				//3.更新兩個賬戶  				accountDao.updateAccount(source);  				int i=1/0;  				accountDao.updateAccount(target);  			}  		}    	2.5.1.5第五步:創建Dao介面和實現類並使用註解讓spring管理  		Dao層介面和AccountRowMapper與基於xml配置的時候相同。略    		@Repository("accountDao")  		public class AccountDaoImpl implements IAccountDao {    			@Autowired  			private JdbcTemplate jdbcTemplate;    			@Override  			public Account findAccountById(Integer id) {  				List<Account> list = jdbcTemplate.query("select * from account where id = ? ",new AccountRowMapper(),id);  				return list.isEmpty()?null:list.get(0);  			}    			@Override  			public Account findAccountByName(String name) {  				List<Account> list =  jdbcTemplate.query("select * from account where name = ? ",new AccountRowMapper(),name);  				if(list.isEmpty()){  					return null;  				}  				if(list.size()>1){  					throw new RuntimeException("結果集不唯一,不是只有一個賬戶對象");  				}  				return list.get(0);  			}    			@Override  			public void updateAccount(Account account) {  				jdbcTemplate.update("update account set money = ? where id = ? ",account.getMoney(),account.getId());  			}  		}    	2.5.2配置步驟  		2.5.2.1第一步:使用@Bean註解配置數據源  		@Bean(name = "dataSource")  			public DataSource createDS() throws Exception {  				DriverManagerDataSource dataSource = new DriverManagerDataSource();  				dataSource.setUsername("root");  				dataSource.setPassword("123");  				dataSource.setDriverClassName("com.mysql.jdbc.Driver");  				dataSource.setUrl("jdbc:mysql:///spring3_day04");  				return dataSource;  			}  	2.5.2.2第二步:使用@Bean註解配置配置事務管理器  		@Bean  		public PlatformTransactionManager  				createTransactionManager(@Qualifier("dataSource") DataSource dataSource) {  			return new DataSourceTransactionManager(dataSource);  		}  		2.5.2.3第三步:使用@Bean註解配置JdbcTemplate  		@Bean  		public JdbcTemplate createTemplate(@Qualifier("dataSource") DataSource dataSource)  		{  			return new JdbcTemplate(dataSource);  		}  	2.5.2.4第四步:在需要控制事務的業務層實現類上使用@Transactional註解  		@Service("accountService")  		@Transactional(readOnly=true,propagation=Propagation.SUPPORTS)  		public class AccountServiceImpl implements IAccountService {    			@Autowired  			private IAccountDao accountDao;    			@Override  			public Account findAccountById(Integer id) {  				return accountDao.findAccountById(id);  			}    			@Override  			@Transactional(readOnly=false,propagation=Propagation.REQUIRED)  			public void transfer(String sourceName, String targeName, Float money) {  				//1.根據名稱查詢兩個賬戶  				Account source = accountDao.findAccountByName(sourceName);  				Account target = accountDao.findAccountByName(targeName);  				//2.修改兩個賬戶的金額  				source.setMoney(source.getMoney()-money);//轉出賬戶減錢  				target.setMoney(target.getMoney()+money);//轉入賬戶加錢  				//3.更新兩個賬戶  				accountDao.updateAccount(source);  				//int i=1/0;  				accountDao.updateAccount(target);  			}  		}    		該註解的屬性和xml中的屬性含義一致。該註解可以出現在介面上,類上和方法上。  		出現介面上,表示該介面的所有實現類都有事務支援。  		出現在類上,表示類中所有方法有事務支援  		出現在方法上,表示方法有事務支援。  		以上三個位置的優先順序:方法>類>介面。  	2.5.2.5第五步:使用@EnableTransactionManagement開啟spring對註解事務的的支援  		@Configuration  		@EnableTransactionManagement  		public class SpringTxConfiguration {  			//裡面配置數據源,配置JdbcTemplate,配置事務管理器。在之前的步驟已經寫過了。  		}    在Spring中開啟事務的案例  	applicationContext3.xml  		<?xml version="1.0" encoding="UTF-8"?>  		<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">    			<!-- 使用Spring整合c3p0的連接池,沒有採用屬性文件的方式 -->  			<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource ">  				<property name="driverClass" value="com.mysql.jdbc.Driver"/>  				<property name="jdbcUrl" value="jdbc:mysql:///spring_04"/>  				<property name="user" value="root"/>  				<property name="password" value="root"/>  			</bean>    			<!-- 配置平台事務管理器 -->  			<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  				<property name="dataSource" ref="dataSource"></property>  			</bean>  			<!-- 配置通知: 是Spring框架提供通知,不是咋們自己編寫的 -->  			<tx:advice id="myAdvice" transaction-manager="transactionManager">  				<tx:attributes>  					<!-- 給具體的業務層的方法進行隔離級別,傳播行為的具體的配置 -->  					<tx:method name="pay" isolation="DEFAULT" propagation="REQUIRED"/>  					<tx:method name="save*" isolation="DEFAULT"></tx:method>  					<tx:method name="find*" read-only="true"></tx:method>  				</tx:attributes>  			</tx:advice>  			<!-- 配置AOP的增強 -->  			<aop:config>  				<!-- Spring框架製作的通知,必須要使用該標籤,如果是自定義的切面,使用aop:aspect標籤 -->  				<aop:advisor advice-ref="myAdvice" pointcut="execution(public * com.baidu.*.*ServiceImpl.*(..))"></aop:advisor>  			</aop:config>    			<!-- 可以注入連接池 -->  			<bean id="accountDao" class="com.baidu.demo3.AccountDaoImpl">  				<property name="dataSource" ref="dataSource"></property>  			</bean>  			<!-- 管理service -->  			<bean id="accountService" class="com.baidu.demo3.AccountServiceImpl">  				<property name="accountDao" ref="accountDao"></property>  			</bean>    		</beans>  在dao層對程式碼進行了優化,優化了JdbcTemplate  	public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {  		/*  	private JdbcTemplate jdbcTemplate;    	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {  		this.jdbcTemplate = jdbcTemplate;  	}*/  	//減錢  	@Override  	public void outMoney(String out, double money) {  		//jdbcTemplate.update("update username set money = money - ? where name = ?",money,out);  		this.getJdbcTemplate().update("update username set money = money - ? where name=?",money,out);  	}  	//加錢  	@Override  	public void inMoney(String in, double money) {  		//jdbcTemplate.update("update username set money = money + ? where name = ?",money,in);  		this.getJdbcTemplate().update("update username set money = money + ? where name=?",money,in);  	}    }    Xml和註解一起進行Spring的事務管理  		applicationContext4.xml  			<?xml version="1.0" encoding="UTF-8"?>  			<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">    				<!-- 開啟註解的掃描 -->  				<context:component-scan base-package="com.baidu"/>  				<!-- 使用Spring整合c3p0的連接池,沒有採用屬性文件的方式 -->  				<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">  					<property name="driverClass" value="com.mysql.jdbc.Driver"/>  					<property name="jdbcUrl" value="jdbc:mysql:///spring_04"/>  					<property name="user" value="root"/>  					<property name="password" value="root"/>  				</bean>    				<!-- 配置JdbcTemplate模板 -->  				<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  					<property name="dataSource" ref="dataSource"></property>  				</bean>  				<!-- 配置平台事務管理器 -->  				<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  					<property name="dataSource" ref="dataSource"></property>  				</bean>  				<!-- 開啟事務註解 -->  				<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>    			</beans>  Service層用註解 :  	//實現類  		@Service("accountService")  		@Transactional(isolation=Isolation.DEFAULT)  		public class AccountServiceImpl implements AccountService {  			@Resource(name="accountDao")  			private AccountDao accountDao;  		//	public void setAccountDao(AccountDao accountDao) {  		//		this.accountDao = accountDao;  		//	}  			//支付的方法  			@Override  			public void pay(String out, String in, double money) {  				//模擬兩個操作  				//減錢  				accountDao.outMoney(out, money);  				//模擬異常  				//int i = 10/0;  				accountDao.inMoney(in, money);  			}  		}  使用純註解的方式進行Spring事務管理 :  		/*  		 * 配置類,Spring聲明式事務管理,純註解的方式  		 *  		 */  		@Configuration  		@ComponentScan(basePackages="com.baidu.demo5")  		@EnableTransactionManagement	//純註解的方式,開啟事務註解  		public class SpringConfig {  			@Bean(name="dataSource")  			public DataSource createDataSource() throws Exception{  				ComboPooledDataSource dataSource = new ComboPooledDataSource();  				dataSource.setDriverClass("com.mysql.jdbc.Driver");  				dataSource.setJdbcUrl("jdbc:mysql:///spring_04");  				dataSource.setUser("root");  				dataSource.setPassword("root");    				return dataSource;  			}    			//把dataSource注入進來  			@Bean(name="jdbcTemplate")  			@Resource(name="dataSource")  			public JdbcTemplate createJdbcTemplate(DataSource dataSource) {  				return new JdbcTemplate(dataSource);  			}    			//創建平台事務管理器對象  			@Bean(name="transactionManager")  			@Resource(name="dataSource")  			public PlatformTransactionManager createTransactionManager(DataSource dataSource) {  				return new DataSourceTransactionManager(dataSource);  			}    		}  1 : 傳播行為 : 解決業務層方法之間互相調用的問題.  	傳播行為的默認值 : 保證save和update方法在同一個事務中.    2 : Spring事務管理 : (1) : XML配置文件 ; (2) : XML+註解配置文件 ; (3) : 純註解  	Spring框架提供了介面和實現類,進行事務管理的.  		PlatformTransactionManager介面 : 平台事務管理器,提供和回滾事務的.  			HibernateTransactionManager : hibernate框架事務管理的實現類.  			DataSourceTransactionManager : 使用JDBC或者MyBattis框架  		TransactionDefinition介面 : 事務的定義的資訊.提供很多常量,分別表示隔離級別,傳播行為.  			傳播行為 : 事務的傳播行為,解決service方法之間的調用的問題.    	Spring聲明式事務管理,使用AOP技術進行事務管理.  		通知/增強 : 事務管理的方法,不用咋們自己編寫.需要配置.    		連接池 DataSource ,存在Connection ,使用JDBC進行事務管理 ,conn.commit()  						|  						|注入  		平台事務管理器(必須配置的),是Spring提供介面,提交和回滾事務  						|  						|注入  		自己編寫通知方法(事務管理),Spring提供通知,配置通知  						|  						|注入  				配置AOP增強 aop:config