• Spring第三天:Spring的AOP的注解开发、Spring的声明式事务、JdbcTemplate


    目录

    1.Spring的AOP基于AspectJ的注解开发

    1.1Spring基于ApsectJ的注解的AOP开发

    1.1.1创建项目,引入jar包

    1.1.2引入配置文件

    1.1.3编写目标类并配置

    1.1.4编写切面类并配置

    1.1.5使用注解的AOP对象目标类进行增强

    1.1.6编写测试类

    1.2Spring的注解的AOP的通知类型

    1.2.1@Before      :前置通知

    1.2.2@AfterReturning  :后置通知

    1.2.3@Around         :环绕通知

    1.2.4@AfterThrowing        :异常抛出通知

    1.2.5@After        :最终通知

    1.3Spring的注解的AOP的切入点的配置

    2.Spring的JDBC的模板的使用

    2.1Spring的JDBC的模板

    2.1.1JDBC模板使用的入门

    2.1.2创建数据库和表

    2.1.3使用JDBC的模板:保存数据

    2.2将连接池和模板交给Spring管理

    2.2.1引入Spring的配置文件

    2.2.2使用Jdbc的模板

    2.3使用开源的数据库连接池:

    2.3.1DBCP的使用

    2.3.2C3P0的使用

    2.4抽取配置到属性文件

    2.4.1定义一个属性文件jdbc.properties

    2.4.2在Spring的配置文件中引入属性文件

    2.4.3引入属性文件的值

    2.4.4测试

    2.5使用JDBC的模板完成CRUD的操作

    2.5.1保存操作

    2.5.2修改操作

    2.5.3删除操作

    2.5.4查询操作

    3.Spring的事务管理

    3.1事务的基本概念

    3.1.1什么事务

    3.1.2事务的特性

    3.1.3如果不考虑隔离性引发安全性问题

    3.1.4解决读问题

    3.2Spring的事务管理的API

    3.2.1PlatformTransactionManager:平台事务管理器

    3.2.2TransactionDefinition :事务定义信息

    3.2.3TransactionStatus:事务的状态

    3.2.4事务管理的API的关系:

    3.3Spring的事务的传播行为

    3.4Spring的事务管理

    3.5Spring的事务管理:第一类:编程式事务(需要手动编写代码)--了解

    3.5.1第一步:配置平台事务管理器

    3.5.2第二步:配置事务管理的模板类

    3.5.3第三步:在业务层注入事务管理的模板

    3.5.4编写事务管理的代码

    3.5.5测试:

    3.6Spring的事务管理:第二类:声明式事务管理(通过配置实现)---AOP

    3.6.1XML方式的声明式事务管理

    3.6.2注解方式的声明式事务管理


     

    1.Spring的AOP基于AspectJ的注解开发

    1.1Spring基于ApsectJ的注解的AOP开发

    1.1.1创建项目,引入jar包

    1.1.2引入配置文件

    1.1.3编写目标类并配置

    目标类:

     

    package com.albertyy.demo1;
    
    
    
    /**  
    
    *   
    
    * 项目名称:SpringDay03_AOP  
    
    * 类名称:OrderDao  
    
    * 类描述:  
    
    * 创建人:yangyangyang  
    
    * 创建时间:2018年12月7日 下午2:58:44  
    
    * 修改人:yangyangyang  
    
    * 修改时间:2018年12月7日 下午2:58:44  
    
    * 修改备注:  
    
    * @version   
    
    *   
    
    */
    
    
    
    public class OrderDao {
    
         public void save(){
    
             System.out.println("保存订单...");
    
         }
    
         public void update(){
    
             System.out.println("修改订单...");
    
         }
    
         public String delete(){
    
             System.out.println("删除订单...");
    
             return "李君莫";
    
         }
    
         public void find(){
    
             System.out.println("查询订单...");
    
    //       int d = 1/0;
    
         }
    
    }

    在配置文件配置中配置目标类:

    <!-- 配置目标类 -->
    
         <bean id="orderDao" class="com.albertyy.demo1.OrderDao">
    
        
    
         </bean>

     

    1.1.4编写切面类并配置

    public class MyAspectAnno {
    
      
    
         public void before(){
    
             System.out.println("前置增强.....");
    
         }
    
    }   
    
    
    <!-- 配置切面类 -->
    
        <bean id="myAspect" class="com.albertyy.demo1.MyAspectAnno">
    
       
    
        </bean>

     

    1.1.5使用注解的AOP对象目标类进行增强

    1. 在配置文件中打开注解的AOP开发
    
    <!-- 在配置文件中开启注解的AOP的开发 -->
    
         <aop:aspectj-autoproxy/>
    1. 在切面类上使用注解


     

    /**  
    
    *   
    
    * 项目名称:SpringDay03_AOP  
    
    * 类名称:MyAspectAnno  
    
    * 类描述:注解的切面类  
    
    * 创建人:yangyangyang  
    
    * 创建时间:2018年12月7日 下午3:00:55  
    
    * 修改人:yangyangyang  
    
    * 修改时间:2018年12月7日 下午3:00:55  
    
    * 修改备注:  
    
    * @version   
    
    *   
    
    */
    
    @Aspect
    
    public class MyAspectAnno {
    
      
    
         @Before(value="execution(* com.albertyy.demo1.OrderDao.save(..))")
    
         public void before(){
    
             System.out.println("前置增强.....");
    
         }
    
        
    
    }
    
    

    1.1.6编写测试类

     

    package com.albertyy.demo1;
    
    
    
    import javax.annotation.Resource;
    
    
    
    import org.junit.Test;
    
    import org.junit.runner.RunWith;
    
    import org.springframework.test.context.ContextConfiguration;
    
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    
    
    /**  
    
    *   
    
    * 项目名称:SpringDay03_AOP  
    
    * 类名称:SpringDemo1  
    
    * 类描述:Spring的AOP的注解开发  
    
    * 创建人:yangyangyang  
    
    * 创建时间:2018年12月7日 下午2:59:42  
    
    * 修改人:yangyangyang  
    
    * 修改时间:2018年12月7日 下午2:59:42  
    
    * 修改备注:  
    
    * @version   
    
    *   
    
    */
    
    
    
    @RunWith(SpringJUnit4ClassRunner.class)
    
    @ContextConfiguration("classpath:applicationContext.xml")
    
    public class SpringDemo1 {
    
         @Resource(name="orderDao")
    
         private OrderDao orderDao;
    
        
    
         @Test
    
         public void demo1(){
    
             orderDao.save();
    
             orderDao.update();
    
             orderDao.delete();
    
             orderDao.find();
    
         }
    
    }
    
    

    1.2Spring的注解的AOP的通知类型

    1.2.1@Before      :前置通知

     

    @Before(value="execution(* com.albertyy.demo1.OrderDao.save(..))")
    
         public void before(){
    
             System.out.println("前置增强.....");
    
         }

    1.2.2@AfterReturning  :后置通知

     

    // 后置通知:
    
         @AfterReturning(value="execution(* com.albertyy.demo1.OrderDao.delete(..))",returning="result")
    
         public void afterReturning(Object result){
    
             System.out.println("后置增强....."+result);
    
         }

    1.2.3@Around         :环绕通知

    // 环绕通知:
    
         @Around(value="execution(* com.albertyy.demo1.OrderDao.update(..))")
    
         public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
    
             System.out.println("环绕前增强.....");
    
             Object obj  = joinPoint.proceed();
    
             System.out.println("环绕后增强.....");
    
             return obj;
    
         }

     

    1.2.4@AfterThrowing        :异常抛出通知

    // 异常抛出通知:
    
         @AfterThrowing(value="execution(* com.albertyy.demo1.OrderDao.find(..))",throwing="e")
    
         public void afterThrowing(Throwable e){
    
             System.out.println("异常抛出增强....."+e.getMessage());
    
         }

    1.2.5@After        :最终通知

    // 最终通知
    
         @After(value="execution(* com.albertyy.demo1.OrderDao.find(..))")
    
         public void after(){
    
             System.out.println("最终增强.......");
    
         }

    1.3Spring的注解的AOP的切入点的配置


     

    package com.albertyy.demo1;
    
    
    
    import org.aspectj.lang.ProceedingJoinPoint;
    
    import org.aspectj.lang.annotation.After;
    
    import org.aspectj.lang.annotation.AfterReturning;
    
    import org.aspectj.lang.annotation.AfterThrowing;
    
    import org.aspectj.lang.annotation.Around;
    
    import org.aspectj.lang.annotation.Aspect;
    
    import org.aspectj.lang.annotation.Before;
    
    import org.aspectj.lang.annotation.Pointcut;
    
    
    
    /**  
    
    *   
    
    * 项目名称:SpringDay03_AOP  
    
    * 类名称:MyAspectAnno  
    
    * 类描述:注解的切面类  
    
    * 创建人:yangyangyang  
    
    * 创建时间:2018年12月7日 下午3:00:55  
    
    * 修改人:yangyangyang  
    
    * 修改时间:2018年12月7日 下午3:00:55  
    
    * 修改备注:  
    
    * @version   
    
    *   
    
    */
    
    @Aspect
    
    public class MyAspectAnno {
    
      
    
         @Before(value="MyAspectAnno.pointcut2()")
    
         public void before(){
    
             System.out.println("前置增强.....");
    
         }
    
        
    
         // 后置通知:
    
         @AfterReturning(value="MyAspectAnno.pointcut4()",returning="result")
    
         public void afterReturning(Object result){
    
             System.out.println("后置增强....."+result);
    
         }
    
        
    
         // 环绕通知:
    
         @Around(value="MyAspectAnno.pointcut3()")
    
         public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
    
             System.out.println("环绕前增强.....");
    
             Object obj  = joinPoint.proceed();
    
             System.out.println("环绕后增强.....");
    
             return obj;
    
         }
    
        
    
         // 异常抛出通知:
    
         @AfterThrowing(value="MyAspectAnno.pointcut1()",throwing="e")
    
         public void afterThrowing(Throwable e){
    
             System.out.println("异常抛出增强....."+e.getMessage());
    
         }
    
        
    
         // 最终通知
    
         @After(value="MyAspectAnno.pointcut1()")
    
         public void after(){
    
             System.out.println("最终增强.......");
    
         }
    
        
    
         // 切入点注解:
    
         @Pointcut(value="execution(* com.albertyy.demo1.OrderDao.find(..))")
    
         private void pointcut1(){}
    
         @Pointcut(value="execution(* com.albertyy.demo1.OrderDao.save(..))")
    
         private void pointcut2(){}
    
         @Pointcut(value="execution(* com.albertyy.demo1.OrderDao.update(..))")
    
         private void pointcut3(){}
    
         @Pointcut(value="execution(* com.albertyy.demo1.OrderDao.delete(..))")
    
         private void pointcut4(){}
    
    }
    
    

    2.Spring的JDBC的模板的使用

    2.1SpringJDBC的模板

    Spring是EE开发的一站式的框架,有EE开发的每层的解决方案。Spring对持久层也提供了解决方案:ORM模块和JDBC的模板

    Spring提供了很多的模板用于简化开发:

    2.1.1JDBC模板使用的入门

    1. 创建项目,引入jar包
      1. 引入基本开发包:
      2. 数据库驱动
      3. Spring的JDBC模板的jar包

    2.1.2创建数据库和表

    create database spring4_day03;
    
    use spring4_day03;
    
    create table account(
    
        id int primary key auto_increment,
    
        name varchar(20),
    
        money double
    
    );

    2.1.3使用JDBC的模板:保存数据

    
    package com.albertyy.jdbc.demo1;
    
    
    
    import org.junit.Test;
    
    import org.springframework.jdbc.core.JdbcTemplate;
    
    import org.springframework.jdbc.datasource.DriverManagerDataSource;
    
    
    
    /**  
    
    *   
    
    * 项目名称:SpringDay03_JDBC  
    
    * 类名称:JdbcDemo1  
    
    * 类描述:JDBC模板的使用  
    
    * 创建人:yangyangyang  
    
    * 创建时间:2018年12月7日 下午4:13:47  
    
    * 修改人:yangyangyang  
    
    * 修改时间:2018年12月7日 下午4:13:47  
    
    * 修改备注:  
    
    * @version   
    
    *   
    
    */
    
    
    
    public class JdbcDemo1 {
    
         @Test
    
         // jdbc模板的使用类似于Dbutils.
    
         public void demo1(){
    
             // 创建连接池:
    
             DriverManagerDataSource dataSource = new DriverManagerDataSource();
    
             dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    
             dataSource.setUrl("jdbc:mysql:///spring4_day03");
    
             dataSource.setUsername("root");
    
             dataSource.setPassword("123456");
    
             // 创建jdbc模板
    
             JdbcTemplate jdbcTemplate = new JdbcTemplate();
    
             jdbcTemplate.setDataSource(dataSource);
    
             jdbcTemplate.update("insert into account values (null,?,?)", "君陌",10000d);
    
         }
    
    }
    
    

    2.2将连接池和模板交给Spring管理

    2.2.1引入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: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的内置的连接池======================== -->
    
         <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    
             <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    
              <property name="url" value="jdbc:mysql:///spring4_day03"/>
    
             <property name="username" value="root"/>
    
             <property name="password" value="123456"/>
    
         </bean>
    
        
    
        
    
         <!-- 配置Spring的JDBC的模板========================= -->
    
         <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    
             <property name="dataSource" ref="dataSource" />
    
         </bean>
    
        
    
    </beans>

     

    2.2.2使用Jdbc的模板

    1. 引入spring_aopjar
    
    package com.albertyy.jdbc.demo1;
    
    
    
    import javax.annotation.Resource;
    
    
    
    import org.junit.Test;
    
    import org.junit.runner.RunWith;
    
    import org.springframework.jdbc.core.JdbcTemplate;
    
    import org.springframework.test.context.ContextConfiguration;
    
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    
    
    /**  
    
    *   
    
    * 项目名称:SpringDay03_JDBC  
    
    * 类名称:JdbcDemo2  
    
    * 类描述: 将连接池和模板交给Spring管理 
    
    * 创建人:yangyangyang  
    
    * 创建时间:2018年12月7日 下午4:35:27  
    
    * 修改人:yangyangyang  
    
    * 修改时间:2018年12月7日 下午4:35:27  
    
    * 修改备注:  
    
    * @version   
    
    *   
    
    */
    
    @RunWith(SpringJUnit4ClassRunner.class)
    
    @ContextConfiguration("classpath:applicationContext.xml")
    
    public class JdbcDemo2 {
    
    
    
         @Resource(name="jdbcTemplate")
    
         private JdbcTemplate jdbcTemplate;
    
        
    
         @Test
    
         // 保存操作
    
         public void demo1(){
    
             jdbcTemplate.update("insert into account values (null,?,?)", "张小花儿",10000d);
    
         }
    
        
    
    }
    
    

    2.3使用开源的数据库连接池:

    2.3.1DBCP的使用

    1. 引入jar包

    1. 配置DBCP连接池
    
    <!-- 配置DBCP连接池=============================== -->
    
         <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    
             <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    
             <property name="url" value="jdbc:mysql:///spring4_day03"/>
    
             <property name="username" value="root"/>
    
             <property name="password" value="123456"/>
    
         </bean>
    
        
    
         <!-- 配置Spring的JDBC的模板========================= -->
    
         <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    
             <property name="dataSource" ref="dataSource" />
    
         </bean>

    2.3.2C3P0的使用

    1. 引入c3p0连接池jar包

    1. 配置c3p0连接池
    
    <!-- 配置C3P0连接池=============================== -->
    
         <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    
             <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    
             <property name="jdbcUrl" value="jdbc:mysql:///spring4_day03"/>
    
             <property name="user" value="root"/>
    
             <property name="password" value="123456"/>
    
         </bean>
    
        
    
         <!-- 配置Spring的JDBC的模板========================= -->
    
         <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    
             <property name="dataSource" ref="dataSource" />
    
         </bean>

     

    2.4抽取配置到属性文件

    2.4.1定义一个属性文件jdbc.properties

     

    jdbc.driverClass=com.mysql.jdbc.Driver
    
    jdbc.url=jdbc:mysql:///spring4_day03
    
    jdbc.username=root
    
    jdbc.password=123456

    2.4.2在Spring的配置文件中引入属性文件

    • 第一种:
    <!-- 第一种方式通过一个bean标签引入的(很少用) -->
    
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    
             <property name="location" value="classpath:jdbc.properties"/>
    
    </bean>

     

    • 第二种:

     

    <!-- 第二种方式通过context标签引入的 -->
    
         <context:property-placeholder location="classpath:jdbc.properties"/>

     

    2.4.3引入属性文件的值

    
    <!-- 配置C3P0连接池=============================== -->
    
         <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    
             <property name="driverClass" value="${jdbc.driverClass}"/>
    
             <property name="jdbcUrl" value="${jdbc.url}"/>
    
             <property name="user" value="${jdbc.username}"/>
    
             <property name="password" value="${jdbc.password}"/>
    
         </bean>

    2.4.4测试

     

    @Test
    
         // 保存操作
    
         public void demo1(){
    
             jdbcTemplate.update("insert into account values (null,?,?)", "十三先生",10000d);
    
         }

    2.5使用JDBC的模板完成CRUD的操作

    2.5.1保存操作

    @Test
    
         // 保存操作
    
         public void demo1(){
    
             jdbcTemplate.update("insert into account values (null,?,?)", "陈皮皮",10000d);
    
         }

    2.5.2修改操作

     

    @Test
    
         // 修改操作
    
         public void demo2(){
    
             jdbcTemplate.update("update account set name = ? ,money = ? where id = ?", "叶红鱼",2000d,1);
    
         }

    2.5.3删除操作

     

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

    2.5.4查询操作

    1. 查询某个属性


     

    @Test
    
         // 查询操作:
    
         public void demo4(){
    
             String name = jdbcTemplate.queryForObject("select name from account where id = ?", String.class, 5);
    
             System.out.println(name);
    
         }
    
        
    
         @Test
    
         // 统计查询
    
         public void demo5(){
    
             Long count = jdbcTemplate.queryForObject("select count(*) from account", Long.class);
    
             System.out.println(count);
    
         }
    
    
    1. 查询返回对象或集合

     

    @Test
    
         // 封装到一个对象中
    
         public void demo6(){
    
             Account account = jdbcTemplate.queryForObject("select * from account where id = ?", new MyRowMapper(), 5);
    
             System.out.println(account);
    
         }
    
        
    
         @Test
    
         // 查询多条记录
    
         public void demo7(){
    
             List<Account> list = jdbcTemplate.query("select * from account", new MyRowMapper());
    
             for (Account account : list) {
    
                  System.out.println(account);
    
             }
    
         }
    
        

     

    • 数据封装

     

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

     

    3.Spring的事务管理

    3.1事务的基本概念

    3.1.1什么事务

    1. 事务:逻辑上的一组操作,组成这组操作的各个单元,要么全都成功,要么全都失败。

    3.1.2事务的特性

    1. 原子性:事务不可分割.
    2. 一致性:事务执行前后数据完整性保持一致。
    3. 隔离性:一个事务的执行不应该受到其他事务的干扰。
    4. 持久性:一旦事务结束,数据就持久化到数据库。

    3.1.3如果不考虑隔离性引发安全性问题

    1. 读问题
      1. 脏读                   :一个事务读到另一个事务未提交的数据
      2. 不可重复读     :一个事务读到另一个事务已经提交的update的数据,导致一个事务中多次查询结果不一致
      3. 虚读、幻读     :一个事务读到另一个事务已经提交的insert的数据,导致一个事务中多次查询结果不一致。
    2. 写问题
      1. 丢失更新

    3.1.4解决读问题

    • 设置事务的隔离级别
      1. Read uncommitted :未提交读,任何读问题都解决不了。
      2. Read committed      :已提交读,解决脏读,但是不可重复读和虚读有可能发生。
      3. Repeatable read      :重复读,解决脏读和不可重复读,但是虚读有可能发生。
      4. Serializable                :解决所有读问题。

    3.2Spring的事务管理的API

    3.2.1PlatformTransactionManager:平台事务管理器

    • 平台事务管理器:接口,是Spring用于管理事务的真正的对象。
      1. DataSourceTransactionManager  :底层使用JDBC管理事务
      2. HibernateTransactionManager       :底层使用Hibernate管理事务

    3.2.2TransactionDefinition :事务定义信息

    • 事务定义:用于定义事务的相关的信息,隔离级别、超时信息、传播行为、是否只读

    3.2.3TransactionStatus:事务的状态

    • 事务状态:用于记录在事务管理过程中,事务的状态的对象。

    3.2.4事务管理的API的关系:

    Spring进行事务管理的时候,首先平台事务管理器根据事务定义信息进行事务的管理,在事务管理过程中,产生各种状态,将这些状态的信息记录到事务状态的对象中。

    3.3Spring的事务的传播行为

    1. Spring中提供了七种事务的传播行为:

    保证多个操作在同一个事务中

    1. PROPAGATION_REQUIRED    :默认值,如果A中有事务,使用A中的事务,如果A没有,创建一个新的事务,将操作包含进来。
    2. PROPAGATION_SUPPORTS    :支持事务,如果A中有事务,使用A中的事务。如果A没有事务,不使用事务。
    3. PROPAGATION_MANDATORY   :如果A中有事务,使用A中的事务。如果A没有事务,抛出异常。

     

    保证多个操作不在同一个事务中

    1. PROPAGATION_REQUIRES_NEW    :如果A中有事务,将A的事务挂起(暂停),创建新事务,只包含自身操作。如果A中没有事务,创建一个新事务,包含自身操作。
    2. PROPAGATION_NOT_SUPPORTED   :如果A中有事务,将A的事务挂起。不使用事务管理。
    3. PROPAGATION_NEVER          :如果A中有事务,报异常。

     

    嵌套式事务

    1. PROPAGATION_NESTED         :嵌套事务,如果A中有事务,按照A的事务执行,执行完成后,设置一个保存点,执行B中的操作,如果没有异常,执行通过,如果有异常,可以选择回滚到最初始位置,也可以回滚到保存点。

    3.4Spring的事务管理

    1. 创建Service的接口和实现类


     

    package com.albertyy.tx.demo1;
    
    
    
    /**
    
     * 转账的业务层的实现类
    
     * @author yxy
    
     *
    
     */
    
    public class AccountServiceImpl implements AccountService {
    
    
    
         // 注入DAO:
    
         private AccountDao accountDao;
    
        
    
         public void setAccountDao(AccountDao accountDao) {
    
             this.accountDao = accountDao;
    
         }
    
    
    
         @Override
    
         /**
    
          * from:转出账号 to:转入账号 money:转账金额
    
          */
    
         public void transfer(final String from, final String to, final Double money) {
    
             accountDao.outMoney(from, money);
    
             int d = 1 / 0;
    
             accountDao.inMoney(to, money);
    
        }
    
    
    
    }
    
    

     

    1. 创建DAO的接口和实现类


     

    package com.albertyy.tx.demo1;
    
    
    
    import org.springframework.jdbc.core.support.JdbcDaoSupport;
    
    
    
    /**
    
     * 转账的DAO的实现类
    
     * @author yxy
    
     *
    
     */
    
    public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
    
    
    
         @Override
    
         public void outMoney(String from, Double money) {
    
             this.getJdbcTemplate().update("update account set money = money - ? where name = ?", money,from);
    
         }
    
    
    
         @Override
    
         public void inMoney(String to, Double money) {
    
             this.getJdbcTemplate().update("update account set money = money + ? where name = ?", money ,to);
    
         }
    
    
    
    }
    
    
    1. 配置Service和DAO:交给Spring管理

     

    <!-- 配置Service -->
    
         <bean id="accountService" class="com.albertyy.tx.demo1.AccountServiceImpl">
    
             <property name="accountDao" ref="accountDao"/>
    
            
    
         </bean>
    
        
    
         <!-- 配置DAO -->
    
         <bean id="accountDao" class="com.albertyy.tx.demo1.AccountDaoImpl">
    
            
    
         </bean>
    1. 在DAO中编写扣钱和加钱方法:
      1. 配置连接池和JDBC的模板

     

    <!-- 配置连接池和JDBC的模板 -->
    
         <!-- 第二种方式通过context标签引入的 -->
    
         <context:property-placeholder location="classpath:jdbc.properties"/>
    
        
    
         <!-- 配置C3P0连接池=============================== -->
    
         <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    
             <property name="driverClass" value="${jdbc.driverClass}"/>
    
             <property name="jdbcUrl" value="${jdbc.url}"/>
    
             <property name="user" value="${jdbc.username}"/>
    
             <property name="password" value="${jdbc.password}"/>
    
    </bean>

     

    • 在DAO注入Jdbc的模板:

     

    <!-- 配置DAO================= -->
    
         <bean id="accountDao" class="com.albertyy.tx.demo1.AccountDaoImpl">
    
             <property name="dataSource" ref="dataSource"/>
    
    </bean>

     

    • 测试

     

    package com.albertyy.tx.demo1;
    
    
    
    import javax.annotation.Resource;
    
    
    
    import org.junit.Test;
    
    import org.junit.runner.RunWith;
    
    import org.springframework.test.context.ContextConfiguration;
    
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    
    
    /**
    
     * 测试转账的环境
    
     * @author yxy
    
     *
    
     */
    
    @RunWith(SpringJUnit4ClassRunner.class)
    
    @ContextConfiguration("classpath:tx.xml")
    
    public class SpringDemo1 {
    
    
    
         @Resource(name="accountService")
    
         private AccountService accountService;
    
        
    
         @Test
    
         public void demo1(){
    
             accountService.transfer("张丫丫", "莫山山", 100d);
    
         }
    
    }

     

    3.5Spring的事务管理:第一类:编程式事务(需要手动编写代码)--了解

    3.5.1第一步:配置平台事务管理器

     

    <!-- 配置平台事务管理器============================= -->
    
         <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    
             <property name="dataSource" ref="dataSource"/>
    
         </bean>

    3.5.2第二步:配置事务管理的模板类

    1. 配置事务的管理的模板类

     

    <!-- 配置事务管理的模板 -->
    
         <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
    
             <property name="transactionManager" ref="transactionManager"/>
    
         </bean>

     

     

    3.5.3第三步:在业务层注入事务管理的模板


        

    <!-- 配置Service============= -->
    
         <bean id="accountService" class="com.albertyy.tx.demo1.AccountServiceImpl">
    
             <property name="accountDao" ref="accountDao"/>
    
             <!-- 注入事务管理的模板 -->
    
             <property name="trsactionTemplate" ref="transactionTemplate"></property>
    
         </bean>

    3.5.4编写事务管理的代码

     

    @Override
    
         /**
    
          * from:转出账号 to:转入账号 money:转账金额
    
          */
    
         public void transfer(final String from, final String to, final Double money) {
    
    
    
             trsactionTemplate.execute(new TransactionCallbackWithoutResult() {
    
                  @Override
    
                  protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
    
                       accountDao.outMoney(from, money);
    
                       int d = 1 / 0;
    
                       accountDao.inMoney(to, money);
    
                  }
    
             });
    
    
    
         }

    3.5.5测试:


     

    @RunWith(SpringJUnit4ClassRunner.class)
    
    @ContextConfiguration("classpath:tx.xml")
    
    public class SpringDemo1 {
    
    
    
         @Resource(name="accountService")
    
         private AccountService accountService;
    
        
    
         @Test
    
         public void demo1(){
    
             accountService.transfer("张丫丫", "莫山山", 100d);
    
         }
    
    }
    
    

    3.6Spring的事务管理:第二类:声明式事务管理(通过配置实现)---AOP

    3.6.1XML方式的声明式事务管理

    1. 第一步:引入aop的开发包
    2. 第二步:恢复没有配置事务的转账环境
    3. 第三步:配置事务管理器

     

    <!-- 配置事务管理器 -->
    
         <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    
             <property name="dataSource" ref="dataSource"/>
    
         </bean>

     

    • 第四步:配置增强
    
    
         <!-- 配置事务的增强=============================== -->
    
         <tx:advice id="txAdvice" transaction-manager="transactionManager">
    
             <tx:attributes>
    
                  <!-- 事务管理的规则 -->
    
                  <!-- <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT"/>
    
                  <tx:method name="update*" propagation="REQUIRED"/>
    
                  <tx:method name="delete*" propagation="REQUIRED"/>
    
                  <tx:method name="find*" read-only="true"/> -->
    
                  <tx:method name="*" propagation="REQUIRED" read-only="false"/>
    
             </tx:attributes>
    
         </tx:advice>
    • 第五步:AOP的配置

     

    <!-- aop的配置 -->
    
         <aop:config>
    
             <aop:pointcut expression="execution(* com.albertyy.tx.demo2.AccountServiceImpl.*(..))" id="pointcut1"/>
    
             <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
    
         </aop:config>
    • 测试

     

    package com.albertyy.tx.demo2;
    
    
    
    import javax.annotation.Resource;
    
    
    
    import org.junit.Test;
    
    import org.junit.runner.RunWith;
    
    import org.springframework.test.context.ContextConfiguration;
    
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    
    
    /**
    
     * 测试转账的环境
    
     * @author yxy
    
     *
    
     */
    
    @RunWith(SpringJUnit4ClassRunner.class)
    
    @ContextConfiguration("classpath:tx2.xml")
    
    public class SpringDemo1 {
    
    
    
         @Resource(name="accountService")
    
         private AccountService accountService;
    
        
    
         @Test
    
         public void demo1(){
    
             accountService.transfer("张丫丫", "莫山山", 100d);
    
         }
    
    }

     

    3.6.2注解方式的声明式事务管理

    1. 第一步:引入aop的开发包
    2. 第二步:恢复没有配置事务的转账环境
    3. 第三步:配置事务管理器

     

    <!-- 配置事务管理器 -->
    
         <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    
             <property name="dataSource" ref="dataSource"/>
    
         </bean>
    • 第四步:开启注解事务

     

    <!-- 开启注解事务 -->
    
         <tx:annotation-driven transaction-manager="transactionManager"/>

     

    • 第五步:在业务层添加注解


     

    @Transactional
    
    public class AccountServiceImpl implements AccountService {
    
    
    • 第六步:测试

     

     

    package com.albertyy.tx.demo3;
    
    
    
    import javax.annotation.Resource;
    
    
    
    import org.junit.Test;
    
    import org.junit.runner.RunWith;
    
    import org.springframework.test.context.ContextConfiguration;
    
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    
    
    /**
    
     * 测试转账的环境
    
     * @author yxy
    
     *
    
     */
    
    @RunWith(SpringJUnit4ClassRunner.class)
    
    @ContextConfiguration("classpath:tx3.xml")
    
    public class SpringDemo1 {
    
    
    
         @Resource(name="accountService")
    
         private AccountService accountService;
    
        
    
         @Test
    
         public void demo1(){
    
             accountService.transfer("陈皮皮", "莫山山", 100d);
    
         }
    
    }

     

     

    源码:链接: https://pan.baidu.com/s/1dTOhQI8DOy5lKWAiCxnfzg 提取码: swbh 复制这段内容后打开百度网盘手机App,操作更方便哦

     

  • 相关阅读:
    U盘PE系统下安装WIN2003和WINXP的方法(非GHOST版)
    自己做U盘急救杀毒
    Windows Server 2003 SP2 企业版 ISO 下载 629M
    解决开机关机慢问题
    一般处理程序
    [转]iframe自适应高度详解(希望对大家有用)非常经典,非同凡响
    ie6下position fixed的失效bug
    php文件上传MAX_FILE_SIZE不起作用的问题
    IE6测试网页显示空白页面
    自己写的面向过程php验证码
  • 原文地址:https://www.cnblogs.com/yangxianyang/p/13675642.html
Copyright © 2020-2023  润新知