1.1 JdbcTemplate概述 : 它是spring框架中提供的一個對象,是對原始JdbcAPI對象的簡單封裝.spring框架為我們提供了很多的操作模板類. ORM持久化技術 模板類 JDBC org.springframework.jdbc.core.J... ...
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);