SSH框架之Spring第四篇

1.1 JdbcTemplate概述 : 
        它是spring框架中提供的一個(gè)對(duì)象,是對(duì)原始JdbcAPI對(duì)象的簡(jiǎn)單封裝.spring框架為我們提供了很多的操作模板類(lèi).
        ORM持久化技術(shù)                        模板類(lèi)
        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.
    在導(dǎo)包的時(shí)候需要導(dǎo)入spring-jdbc-4.24.RELEASF.jar,還需要導(dǎo)入一個(gè)spring-tx-4.2.4.RELEASE.jar(它和事務(wù)有關(guān))

    <!-- 配置數(shù)據(jù)源 -->
        <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內(nèi)置數(shù)據(jù)源
        spring框架也提供了一個(gè)內(nèi)置數(shù)據(jù)源谐宙,我們也可以使用spring的內(nèi)置數(shù)據(jù)源奈揍,它就在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將數(shù)據(jù)庫(kù)連接的信息配置到屬性文件中:
        【定義屬性文件】
        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前期準(zhǔn)備
        創(chuàng)建數(shù)據(jù)庫(kù):
        create database spring_day04;
        use spring_day04;
        創(chuàng)建表:
        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">

            <!-- 配置一個(gè)數(shù)據(jù)庫(kù)的操作模板:JdbcTemplate -->
            <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
                <property name="dataSource" ref="dataSource"></property>
            </bean>
            
            <!-- 配置數(shù)據(jù)源 -->
            <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.根據(jù)id獲取bean對(duì)象
                JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
                //3.執(zhí)行操作
                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.根據(jù)id獲取bean對(duì)象
                JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
                //3.執(zhí)行操作
                //保存
                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.根據(jù)id獲取bean對(duì)象
                JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
                //3.執(zhí)行操作
                //修改
                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.根據(jù)id獲取bean對(duì)象
                JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
                //3.執(zhí)行操作
                //刪除
                jt.update("delete from account where id = ?",6);
            }
        }
    1.4.7查詢(xún)所有操作
        public class JdbcTemplateDemo3 {
            public static void main(String[] args) {

                //1.獲取Spring容器
                ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
                //2.根據(jù)id獲取bean對(duì)象
                JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
                //3.執(zhí)行操作
                //查詢(xún)所有
                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查詢(xún)一個(gè)操作
        使用RowMapper的方式:常用的方式
        public class JdbcTemplateDemo3 {
            public static void main(String[] args) {

                //1.獲取Spring容器
                ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
                //2.根據(jù)id獲取bean對(duì)象
                JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
                //3.執(zhí)行操作
                //查詢(xún)一個(gè)
                List<Account> as = jt.query("select * from account where id = ? ", 
                                                new AccountRowMapper(), 55);
                System.out.println(as.isEmpty()?"沒(méi)有結(jié)果":as.get(0));
            }
        }
    1.4.9查詢(xún)返回一行一列操作
        public class JdbcTemplateDemo3 {
            public static void main(String[] args) {

                //1.獲取Spring容器
                ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
                //2.根據(jù)id獲取bean對(duì)象
                JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
                //3.執(zhí)行操作
                //查詢(xún)返回一行一列:使用聚合函數(shù)领猾,在不使用group by字句時(shí),都是返回一行一列澡刹。最長(zhǎng)用的就是分頁(yè)中獲取總記錄條數(shù)
                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管理連接池對(duì)象,Spring內(nèi)置的連接池對(duì)象 -->
            
            <!-- <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> -->
            
            <!-- 配置數(shù)據(jù)源,使用Spring整合dbcp連接,沒(méi)有導(dǎo)入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的連接池,沒(méi)有采用屬性文件的方式 -->
            <!-- 
            <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標(biāo)簽,讀取屬性文件 -->
            <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測(cè)試 :
    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的方式入門(mén)
     * @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);
        }
        
        /**
         * 查詢(xún)多條數(shù)據(jù)
         */
        @Test
        public void run4(){
            // sql          sql語(yǔ)句
            // rowMapper    提供封裝數(shù)據(jù)的接口,自己提供實(shí)現(xiàn)類(lèi)(自己封裝數(shù)據(jù)的)
            List<Account> list = jdbcTemplate.query("select * from account", new BeanMapper());
            for (Account account : list) {
                System.out.println(account);
            }
        }   
    }

    /**
     * 自己封裝的實(shí)現(xiàn)類(lèi)然想,封裝數(shù)據(jù)的
     * @author Administrator
     */
    class BeanMapper implements RowMapper<Account>{
        
        /**
         * 一行一行封裝數(shù)據(jù)的
         */
        public Account mapRow(ResultSet rs, int index) throws SQLException {
            // 創(chuàng)建Account對(duì)象哟沫,一個(gè)屬性一個(gè)屬性賦值,返回對(duì)象
            Account ac = new Account();
            ac.setId(rs.getInt("id"));
            ac.setName(rs.getString("name"));
            ac.setMoney(rs.getDouble("money"));
            return ac;
        }
        
    }

2,1 Spring 事務(wù)控制我們要明確的
    1: JavaEE體系進(jìn)行分層開(kāi)發(fā),事務(wù)處理位于業(yè)務(wù)層,Spring提供了分層設(shè)計(jì)業(yè)務(wù)層的事務(wù)處理解決方案.
    2: Spring框架為我們提供就一組事務(wù)控制的接口.這組接口是在spring-tx-4.2.4RELEASE.jar中.
    3: spring的事務(wù)都是基于AOP的,它既可以使用編程的方式實(shí)現(xiàn),也可以使用配置的方式實(shí)現(xiàn)
    2.2Spring中事務(wù)控制的API介紹
        2.2.1PlatformTransactionManager
        此接口是spring的事務(wù)管理器巍耗,它里面提供了我們常用的操作事務(wù)的方法秋麸,如下圖:

        我們?cè)陂_(kāi)發(fā)中都是使用它的實(shí)現(xiàn)類(lèi),如下圖:

        真正管理事務(wù)的對(duì)象
        org.springframework.jdbc.datasource.DataSourceTransactionManager    使用Spring JDBC或iBatis 進(jìn)行持久化數(shù)據(jù)時(shí)使用
        org.springframework.orm.hibernate3.HibernateTransactionManager      使用Hibernate版本進(jìn)行持久化數(shù)據(jù)時(shí)使用
    2.2.2TransactionDefinition
        它是事務(wù)的定義信息對(duì)象炬太,里面有如下方法:

    2.2.2.1事務(wù)的隔離級(jí)別

    2.2.2.2事務(wù)的傳播行為
        REQUIRED:如果當(dāng)前沒(méi)有事務(wù)灸蟆,就新建一個(gè)事務(wù),如果已經(jīng)存在一個(gè)事務(wù)中亲族,加入到這個(gè)事務(wù)中炒考。一般的選擇(默認(rèn)值)
        SUPPORTS:支持當(dāng)前事務(wù),如果當(dāng)前沒(méi)有事務(wù)霎迫,就以非事務(wù)方式執(zhí)行(沒(méi)有事務(wù))
        MANDATORY:使用當(dāng)前的事務(wù)斋枢,如果當(dāng)前沒(méi)有事務(wù),就拋出異常
        REQUERS_NEW:新建事務(wù)知给,如果當(dāng)前在事務(wù)中瓤帚,把當(dāng)前事務(wù)掛起。
        NOT_SUPPORTED:以非事務(wù)方式執(zhí)行操作涩赢,如果當(dāng)前存在事務(wù)戈次,就把當(dāng)前事務(wù)掛起
        NEVER:以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù)筒扒,拋出異常
        NESTED:如果當(dāng)前存在事務(wù)怯邪,則在嵌套事務(wù)內(nèi)執(zhí)行。如果當(dāng)前沒(méi)有事務(wù)花墩,則執(zhí)行REQUIRED類(lèi)似的操作悬秉。
        2.2.2.3超時(shí)時(shí)間
        默認(rèn)值是-1,沒(méi)有超時(shí)限制观游。如果有搂捧,以秒為單位進(jìn)行設(shè)置驮俗。
        2.2.2.4是否是只讀事務(wù)
        建議查詢(xún)時(shí)設(shè)置為只讀懂缕。
        2.2.3TransactionStatus
        此接口提供的是事務(wù)具體的運(yùn)行狀態(tài),方法介紹如下圖:

    2.3基于XML的聲明式事務(wù)控制(配置方式)重點(diǎn)
        2.3.1環(huán)境搭建
        2.3.1.1第一步:拷貝必要的jar包到工程的lib目錄

    2.3.1.2第二步:創(chuàng)建spring的配置文件并導(dǎo)入約束
        <?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第三步:準(zhǔn)備數(shù)據(jù)庫(kù)表和實(shí)體類(lèi)
        創(chuàng)建數(shù)據(jù)庫(kù):
        create database spring_day04;
        use spring_day04;
        創(chuàng)建表:
        create table account(
            id int primary key auto_increment,
            name varchar(40),
            money float
        )character set utf8 collate utf8_general_ci;
        /**
         * 賬戶(hù)的實(shí)體
         */
        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第四步:編寫(xiě)業(yè)務(wù)層接口和實(shí)現(xiàn)類(lèi)
        /**
         * 賬戶(hù)的業(yè)務(wù)層接口
         */
        public interface IAccountService {
            
            /**
             * 根據(jù)id查詢(xún)賬戶(hù)信息
             * @param id
             * @return
             */
            Account findAccountById(Integer id);//查
            
            /**
             * 轉(zhuǎn)賬
             * @param sourceName    轉(zhuǎn)出賬戶(hù)名稱(chēng)
             * @param targeName     轉(zhuǎn)入賬戶(hù)名稱(chēng)
             * @param money         轉(zhuǎn)賬金額
             */
            void transfer(String sourceName,String targeName,Float money);//增刪改
        }

        /**
         * 賬戶(hù)的業(yè)務(wù)層實(shí)現(xiàn)類(lèi)
         */
        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.根據(jù)名稱(chēng)查詢(xún)兩個(gè)賬戶(hù)
                Account source = accountDao.findAccountByName(sourceName);
                Account target = accountDao.findAccountByName(targeName);
                //2.修改兩個(gè)賬戶(hù)的金額
                source.setMoney(source.getMoney()-money);//轉(zhuǎn)出賬戶(hù)減錢(qián)
                target.setMoney(target.getMoney()+money);//轉(zhuǎn)入賬戶(hù)加錢(qián)
                //3.更新兩個(gè)賬戶(hù)
                accountDao.updateAccount(source);
                int i=1/0;
                accountDao.updateAccount(target);
            }
        }
        2.3.1.5第五步:編寫(xiě)Dao接口和實(shí)現(xiàn)類(lèi)
        /**
         * 賬戶(hù)的持久層接口
         */
        public interface IAccountDao {
            
            /**
             * 根據(jù)id查詢(xún)賬戶(hù)信息
             * @param id
             * @return
             */
            Account findAccountById(Integer id);

            /**
             * 根據(jù)名稱(chēng)查詢(xún)賬戶(hù)信息
             * @return
             */
            Account findAccountByName(String name);
            
            /**
             * 更新賬戶(hù)信息
             * @param account
             */
            void updateAccount(Account account);
        }
        /**
         * 賬戶(hù)的持久層實(shí)現(xiàn)類(lèi)
         * 此版本dao王凑,只需要給它的父類(lèi)注入一個(gè)數(shù)據(jù)源
         */
        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("結(jié)果集不唯一搪柑,不是只有一個(gè)賬戶(hù)對(duì)象");
                }
                return list.get(0);
            }

            @Override
            public void updateAccount(Account account) {
                getJdbcTemplate().update("update account set money = ? where id = ? ",account.getMoney(),account.getId());
            }
        }

        /**
         * 賬戶(hù)的封裝類(lèi)RowMapper的實(shí)現(xiàn)類(lèi)
         */
        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第六步:在配置文件中配置業(yè)務(wù)層和持久層對(duì)
        <!-- 配置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>
            
        <!-- 配置數(shù)據(jù)源 -->
        <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第一步:配置事務(wù)管理器
        <!-- 配置一個(gè)事務(wù)管理器 -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <!-- 注入DataSource -->
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        2.3.2.2第二步:配置事務(wù)的通知引用事務(wù)管理器
        <!-- 事務(wù)的配置 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
        </tx:advice>
        2.3.2.3第三步:配置事務(wù)的屬性
        <!--在tx:advice標(biāo)簽內(nèi)部 配置事務(wù)的屬性 -->
        <tx:attributes>
        <!-- 指定方法名稱(chēng):是業(yè)務(wù)核心方法 
            read-only:是否是只讀事務(wù)聋丝。默認(rèn)false,不只讀工碾。
            isolation:指定事務(wù)的隔離級(jí)別弱睦。默認(rèn)值是使用數(shù)據(jù)庫(kù)的默認(rèn)隔離級(jí)別。 
            propagation:指定事務(wù)的傳播行為渊额。
            timeout:指定超時(shí)時(shí)間况木。默認(rèn)值為:-1。永不超時(shí)旬迹。
            rollback-for:用于指定一個(gè)異常火惊,當(dāng)執(zhí)行產(chǎn)生該異常時(shí),事務(wù)回滾奔垦。產(chǎn)生其他異常屹耐,事務(wù)不回滾。沒(méi)有默認(rèn)值椿猎,任何異常都回滾惶岭。
            no-rollback-for:用于指定一個(gè)異常,當(dāng)產(chǎn)生該異常時(shí)犯眠,事務(wù)不回滾按灶,產(chǎn)生其他異常時(shí),事務(wù)回滾阔逼。沒(méi)有默認(rèn)值兆衅,任何異常都回滾。
            -->
            <tx:method name="*" read-only="false" propagation="REQUIRED"/>
            <tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
        </tx:attributes>
        2.3.2.4第四步:配置AOP-切入點(diǎn)表達(dá)式
        <!-- 配置aop -->
        <aop:config>
            <!-- 配置切入點(diǎn)表達(dá)式 -->
            <aop:pointcut expression="execution(* com.baidu.service.impl.*.*(..))" id="pt1"/>
        </aop:config>
        2.3.2.5第五步:配置切入點(diǎn)表達(dá)式和事務(wù)通知的對(duì)應(yīng)關(guān)系
        <!-- 在aop:config標(biāo)簽內(nèi)部:建立事務(wù)的通知和切入點(diǎn)表達(dá)式的關(guān)系 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>
        2.4基于XML和注解組合使用的整合方式
        2.4.1環(huán)境搭建
        2.4.1.1第一步:拷貝必備的jar包到工程的lib目錄

        2.4.1.2第二步:創(chuàng)建spring的配置文件導(dǎo)入約束并配置掃描的包
        <?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第三步:創(chuàng)建數(shù)據(jù)庫(kù)表和實(shí)體類(lèi)
        和基于xml的配置相同嗜浮。
        2.4.1.4第四步:創(chuàng)建業(yè)務(wù)層接口和實(shí)現(xiàn)類(lèi)并使用注解讓spring管理
        業(yè)務(wù)層接口和基于xml配置的時(shí)候相同羡亩。略

        /**
         * 賬戶(hù)的業(yè)務(wù)層實(shí)現(xiàn)類(lèi)
         */
        @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.根據(jù)名稱(chēng)查詢(xún)兩個(gè)賬戶(hù)
                Account source = accountDao.findAccountByName(sourceName);
                Account target = accountDao.findAccountByName(targeName);
                //2.修改兩個(gè)賬戶(hù)的金額
                source.setMoney(source.getMoney()-money);//轉(zhuǎn)出賬戶(hù)減錢(qián)
                target.setMoney(target.getMoney()+money);//轉(zhuǎn)入賬戶(hù)加錢(qián)
                //3.更新兩個(gè)賬戶(hù)
                accountDao.updateAccount(source);
                int i=1/0;
                accountDao.updateAccount(target);
            }
        }
    2.4.1.5第五步:創(chuàng)建Dao接口和實(shí)現(xiàn)類(lèi)并使用注解讓spring管理
        Dao層接口和AccountRowMapper與基于xml配置的時(shí)候相同。略

        @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("結(jié)果集不唯一危融,不是只有一個(gè)賬戶(hù)對(duì)象");
                }
                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第一步:配置數(shù)據(jù)源和JdbcTemplate
        <!-- 配置數(shù)據(jù)源 -->
        <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第二步:配置事務(wù)管理器并注入數(shù)據(jù)源
        <!-- 配置JdbcTemplate -->
        <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
    2.4.2.3第三步:在業(yè)務(wù)層使用@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.根據(jù)名稱(chēng)查詢(xún)兩個(gè)賬戶(hù)
                Account source = accountDao.findAccountByName(sourceName);
                Account target = accountDao.findAccountByName(targeName);
                //2.修改兩個(gè)賬戶(hù)的金額
                source.setMoney(source.getMoney()-money);//轉(zhuǎn)出賬戶(hù)減錢(qián)
                target.setMoney(target.getMoney()+money);//轉(zhuǎn)入賬戶(hù)加錢(qián)
                //3.更新兩個(gè)賬戶(hù)
                accountDao.updateAccount(source);
                //int i=1/0;
                accountDao.updateAccount(target);
            }
        }

        該注解的屬性和xml中的屬性含義一致畏铆。該注解可以出現(xiàn)在接口上,類(lèi)上和方法上吉殃。
        出現(xiàn)接口上辞居,表示該接口的所有實(shí)現(xiàn)類(lèi)都有事務(wù)支持。
        出現(xiàn)在類(lèi)上蛋勺,表示類(lèi)中所有方法有事務(wù)支持
        出現(xiàn)在方法上瓦灶,表示方法有事務(wù)支持。
        以上三個(gè)位置的優(yōu)先級(jí):方法>類(lèi)>接口
    2.4.2.4第四步:在配置文件中開(kāi)啟spring對(duì)注解事務(wù)的支持
        <!-- 開(kāi)啟spring對(duì)注解事務(wù)的支持 -->
        <tx:annotation-driven transaction-manager="transactionManager"/> 
        2.5基于純注解的聲明式事務(wù)控制(配置方式)重點(diǎn)
        2.5.1環(huán)境搭建
        2.5.1.1第一步:拷貝必備的jar包到工程的lib目錄

        2.5.1.2第二步:創(chuàng)建一個(gè)類(lèi)用于加載spring的配置并指定要掃描的包
        /**
         * 用于初始化spring容器的配置類(lèi)
         */
        @Configuration
        @ComponentScan(basePackages="com.baidu")
        public class SpringConfiguration {

        }
    2.5.1.3第三步:創(chuàng)建數(shù)據(jù)庫(kù)表和實(shí)體類(lèi)
        和基于xml的配置相同抱完。略
    2.5.1.4第四步:創(chuàng)建業(yè)務(wù)層接口和實(shí)現(xiàn)類(lèi)并使用注解讓spring管理
        業(yè)務(wù)層接口和基于xml配置的時(shí)候相同贼陶。略

        /**
         * 賬戶(hù)的業(yè)務(wù)層實(shí)現(xiàn)類(lèi)
         */
        @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.根據(jù)名稱(chēng)查詢(xún)兩個(gè)賬戶(hù)
                Account source = accountDao.findAccountByName(sourceName);
                Account target = accountDao.findAccountByName(targeName);
                //2.修改兩個(gè)賬戶(hù)的金額
                source.setMoney(source.getMoney()-money);//轉(zhuǎn)出賬戶(hù)減錢(qián)
                target.setMoney(target.getMoney()+money);//轉(zhuǎn)入賬戶(hù)加錢(qián)
                //3.更新兩個(gè)賬戶(hù)
                accountDao.updateAccount(source);
                int i=1/0;
                accountDao.updateAccount(target);
            }
        }

    2.5.1.5第五步:創(chuàng)建Dao接口和實(shí)現(xiàn)類(lèi)并使用注解讓spring管理
        Dao層接口和AccountRowMapper與基于xml配置的時(shí)候相同。略

        @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("結(jié)果集不唯一,不是只有一個(gè)賬戶(hù)對(duì)象");
                }
                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注解配置數(shù)據(jù)源
        @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注解配置配置事務(wù)管理器
        @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第四步:在需要控制事務(wù)的業(yè)務(wù)層實(shí)現(xiàn)類(lèi)上使用@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.根據(jù)名稱(chēng)查詢(xún)兩個(gè)賬戶(hù)
                Account source = accountDao.findAccountByName(sourceName);
                Account target = accountDao.findAccountByName(targeName);
                //2.修改兩個(gè)賬戶(hù)的金額
                source.setMoney(source.getMoney()-money);//轉(zhuǎn)出賬戶(hù)減錢(qián)
                target.setMoney(target.getMoney()+money);//轉(zhuǎn)入賬戶(hù)加錢(qián)
                //3.更新兩個(gè)賬戶(hù)
                accountDao.updateAccount(source);
                //int i=1/0;
                accountDao.updateAccount(target);
            }
        }

        該注解的屬性和xml中的屬性含義一致碉怔。該注解可以出現(xiàn)在接口上烘贴,類(lèi)上和方法上。
        出現(xiàn)接口上撮胧,表示該接口的所有實(shí)現(xiàn)類(lèi)都有事務(wù)支持桨踪。
        出現(xiàn)在類(lèi)上,表示類(lèi)中所有方法有事務(wù)支持
        出現(xiàn)在方法上芹啥,表示方法有事務(wù)支持锻离。
        以上三個(gè)位置的優(yōu)先級(jí):方法>類(lèi)>接口。
    2.5.2.5第五步:使用@EnableTransactionManagement開(kāi)啟spring對(duì)注解事務(wù)的的支持
        @Configuration
        @EnableTransactionManagement
        public class SpringTxConfiguration {
            //里面配置數(shù)據(jù)源墓怀,配置JdbcTemplate,配置事務(wù)管理器纳账。在之前的步驟已經(jīng)寫(xiě)過(guò)了。
        }

在Spring中開(kāi)啟事務(wù)的案例
    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的連接池,沒(méi)有采用屬性文件的方式 -->
            <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>
            
            <!-- 配置平臺(tái)事務(wù)管理器 -->
            <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <property name="dataSource" ref="dataSource"></property>
            </bean>
            <!-- 配置通知: 是Spring框架提供通知,不是咋們自己編寫(xiě)的 -->
            <tx:advice id="myAdvice" transaction-manager="transactionManager">
                <tx:attributes>
                    <!-- 給具體的業(yè)務(wù)層的方法進(jìn)行隔離級(jí)別,傳播行為的具體的配置 -->
                    <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的增強(qiáng) -->
            <aop:config>
                <!-- Spring框架制作的通知,必須要使用該標(biāo)簽,如果是自定義的切面,使用aop:aspect標(biāo)簽 -->
                <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層對(duì)代碼進(jìn)行了優(yōu)化,優(yōu)化了JdbcTemplate
    public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
        /*
    private JdbcTemplate jdbcTemplate;
    
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }*/
    //減錢(qián)
    @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);
    }
    //加錢(qián)
    @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和注解一起進(jìn)行Spring的事務(wù)管理
        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">
                
                <!-- 開(kāi)啟注解的掃描 -->
                <context:component-scan base-package="com.baidu"/>
                <!-- 使用Spring整合c3p0的連接池,沒(méi)有采用屬性文件的方式 -->
                <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>
                <!-- 配置平臺(tái)事務(wù)管理器 -->
                <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                    <property name="dataSource" ref="dataSource"></property>
                </bean>
                <!-- 開(kāi)啟事務(wù)注解 -->
                <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
                
            </beans>
Service層用注解 :
    //實(shí)現(xiàn)類(lèi)
        @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) {
                //模擬兩個(gè)操作
                //減錢(qián)
                accountDao.outMoney(out, money);
                //模擬異常
                //int i = 10/0;
                accountDao.inMoney(in, money);
            }
        }
使用純注解的方式進(jìn)行Spring事務(wù)管理 :
        /*
         * 配置類(lèi),Spring聲明式事務(wù)管理,純注解的方式
         * 
         */
        @Configuration
        @ComponentScan(basePackages="com.baidu.demo5")
        @EnableTransactionManagement    //純注解的方式,開(kāi)啟事務(wù)注解
        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注入進(jìn)來(lái)
            @Bean(name="jdbcTemplate")
            @Resource(name="dataSource")
            public JdbcTemplate createJdbcTemplate(DataSource dataSource) {
                return new JdbcTemplate(dataSource);
            }
            
            //創(chuàng)建平臺(tái)事務(wù)管理器對(duì)象
            @Bean(name="transactionManager")
            @Resource(name="dataSource")
            public PlatformTransactionManager createTransactionManager(DataSource dataSource) {
                return new DataSourceTransactionManager(dataSource);
            }
            
        }
1 : 傳播行為 : 解決業(yè)務(wù)層方法之間互相調(diào)用的問(wèn)題.
    傳播行為的默認(rèn)值 : 保證save和update方法在同一個(gè)事務(wù)中.

2 : Spring事務(wù)管理 : (1) : XML配置文件 ; (2) : XML+注解配置文件 ; (3) : 純注解
    Spring框架提供了接口和實(shí)現(xiàn)類(lèi),進(jìn)行事務(wù)管理的.
        PlatformTransactionManager接口 : 平臺(tái)事務(wù)管理器,提供和回滾事務(wù)的.
            HibernateTransactionManager : hibernate框架事務(wù)管理的實(shí)現(xiàn)類(lèi).
            DataSourceTransactionManager : 使用JDBC或者M(jìn)yBattis框架
        TransactionDefinition接口 : 事務(wù)的定義的信息.提供很多常量,分別表示隔離級(jí)別,傳播行為.
            傳播行為 : 事務(wù)的傳播行為,解決service方法之間的調(diào)用的問(wèn)題.
        
    Spring聲明式事務(wù)管理,使用AOP技術(shù)進(jìn)行事務(wù)管理.
        通知/增強(qiáng) : 事務(wù)管理的方法,不用咋們自己編寫(xiě).需要配置.
        
        連接池 DataSource ,存在Connection ,使用JDBC進(jìn)行事務(wù)管理 ,conn.commit()
                        |
                        |注入
        平臺(tái)事務(wù)管理器(必須配置的),是Spring提供接口,提交和回滾事務(wù)
                        |
                        |注入
        自己編寫(xiě)通知方法(事務(wù)管理),Spring提供通知,配置通知
                        |
                        |注入
                配置AOP增強(qiáng) aop:config
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末捺疼,一起剝皮案震驚了整個(gè)濱河市疏虫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌啤呼,老刑警劉巖卧秘,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異官扣,居然都是意外死亡翅敌,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)惕蹄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蚯涮,“玉大人,你說(shuō)我怎么就攤上這事卖陵≡舛ィ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵泪蔫,是天一觀的道長(zhǎng)棒旗。 經(jīng)常有香客問(wèn)我,道長(zhǎng)撩荣,這世上最難降的妖魔是什么铣揉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮餐曹,結(jié)果婚禮上逛拱,老公的妹妹穿的比我還像新娘。我一直安慰自己台猴,他們只是感情好朽合,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布额湘。 她就那樣靜靜地躺著,像睡著了一般旁舰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嗡官,一...
    開(kāi)封第一講書(shū)人閱讀 52,682評(píng)論 1 312
  • 那天箭窜,我揣著相機(jī)與錄音,去河邊找鬼衍腥。 笑死磺樱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的婆咸。 我是一名探鬼主播竹捉,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼尚骄!你這毒婦竟也來(lái)了块差?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤倔丈,失蹤者是張志新(化名)和其女友劉穎憨闰,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體需五,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鹉动,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宏邮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泽示。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蜜氨,靈堂內(nèi)的尸體忽然破棺而出械筛,到底是詐尸還是另有隱情,我是刑警寧澤飒炎,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布变姨,位于F島的核電站,受9級(jí)特大地震影響厌丑,放射性物質(zhì)發(fā)生泄漏定欧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一怒竿、第九天 我趴在偏房一處隱蔽的房頂上張望砍鸠。 院中可真熱鬧,春花似錦耕驰、人聲如沸爷辱。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)饭弓。三九已至双饥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間弟断,已是汗流浹背咏花。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留阀趴,地道東北人昏翰。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像刘急,于是被迫代替她去往敵國(guó)和親棚菊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容