小案例-转账

2019-12-04  本文已影响0人  Fultom

转账

1.1 搭建环境

创建表

CREATE DATABASE ee19_spring_day03;
USE ee19_spring_day03;
CREATE TABLE account(
    id INT PRIMARY KEY auto_increment,
    username VARCHAR(50),
    money INT
);
INSERT INTO account(username,money) VALUES('jack','10000');
INSERT INTO account(username,money) VALUES('rose','10000');

1.2.1 Dao层

public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
    @Override
    public void out(String outer, Integer money) {
        this.getJdbcTemplate().update("update account set money = money - ? where username = ?",money,outer);

    }

    @Override
    public void in(String inner, Integer money) {
        this.getJdbcTemplate().update("update account set money = money + ? where username = ?",money,inner);
    }
}

1.2.2 service层

public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Override
    public void transfer(String outer, String inner, Integer money) {
        accountDao.out(outer,money);
        // 断电
//        int i=1/0;
        accountDao.in(inner,money);
    }
}

1.2.3 spring配置文件

 <!--DataSource-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ee19_spring_day03"></property>
        <property name="user" value="root"></property>
        <property name="password" value="12345678"></property>
    </bean>

    <!--dao-->
    <bean id="accountDao" class="com.xft.dao.impl.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--service-->
    <bean id="accountService" class="com.xft.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>

1.2.4 测试

public class TestApp {
    @Test
    public void demo01(){
        String xmlPath = "applicationContext.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
        AccountService accountService = applicationContext.getBean("accountService",AccountService.class);
        accountService.transfer("jack","rose",100);
    }
}

1.3 手动管理事务

  1. 需要获得TransactionTemplate
  2. spring配置模板,并注入给service
  3. 模板需要注入事务管理器
  4. 配置事务管理器DataSourceTransactionManager,需要注入DataSource

1.3.1 修改service


    //需要spring注入模板
    private TransactionTemplate transactionTemplate;
    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    @Override
    public void transfer(String outer, String inner, Integer money) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                accountDao.out(outer,money);
                // 断电
//        int i=1/0;
                accountDao.in(inner,money);
            }
        });
    }

1.3.2 修改spring配置


    <!--service-->
    <bean id="accountService" class="com.xft.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
        <property name="transactionTemplate" ref="transactionTemplate"></property>
    </bean>

    <!--创建模板-->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="txManager"></property>
    </bean>

    <!--配置事务管理器 管理器需要事务,事务从Connection获得,连接从连接池DataSource获得 -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

1.4 工厂 bean 生成代理:半自动

  1. getBean() 获得代理对象
public class TestApp {
    @Test
    public void demo01(){
        String xmlPath = "applicationContext.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
        AccountService accountService = applicationContext.getBean("proxyAccountService",AccountService.class);
        accountService.transfer("jack","rose",100);
    }
}
  1. spring配置一个代理
<!--4 service 代理对象
        4.1  proxyInterfaces接口
        4.2  target目标类
        4.3  transactionManager 事务管理器
        4.4  transactionAttributes 事务属性(事务详情)
             prop key :确定哪些方法使用当前事务配置
             prop.text: 用于配置事务详情
                格式: PROPAGATION,ISOLATION,readOnly,-Exception,+Exception
                        传播行为    隔离级别    是否只读    异常回滚    异常提交
                例如:<prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly</prop> 默认的传播行为和隔离级别
    -->
    <bean id="proxyAccountService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="proxyInterfaces" value="com.xft.service.AccountService"></property>
        <property name="target" ref="accountService"></property>
        <property name="transactionManager" ref="txManager"></property>
        <property name="transactionAttributes">
            <props>
                <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop>
            </props>
        </property>

    </bean>

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

1.5 AOP 配置基于xml(重要)

  1. 配置管理器
  2. 配置事务详情
  3. 配置aop
<!--==============aop配置=================-->
    <!--4 事务管理-->
    <!--4.1 事务管理器-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--4.2 事务详情(事务通知) ,在aop筛选的基础上,对abc 三个确定使用什么样的事务 例如ac 读写 b只读
        <tx:attributes> 用于配置事务详情(事务属性)
        <tx:method name="transfer"/> 详情的具体配置
            propagation 传播行为 REQUIRED:必须
            issolaton  隔离级别
    -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="transfer" propagation="REQUIRES_NEW" isolation="DEFAULT"/>
        </tx:attributes>
    </tx:advice>


    <!--4.3 AOP 编程目标有abcd(四个切入点),切入点表达式确定增强的连接器 从而获得切入点ABC-->
    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.xft.service..*.*(..))"/>
    </aop:config>

1.6 AOP 配置基于注解[重要]

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

    <!--4.2 将管理器交于spring
        transaction-manager 配置事务管理器
        proxy-target-class true : 底层强制使用cglib 代理
    -->
    <tx:annotation-driven transaction-manager="txManager"/>

service 层

@Transactional
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    //需要spring注入模板
    private TransactionTemplate transactionTemplate;
    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }


    @Override
    public void transfer(String outer, String inner, Integer money) {
 doInTransactionWithoutResult(TransactionStatus transactionStatus) {

        accountDao.out(outer,money);
        // 断电
//                int i=1/0;
        accountDao.in(inner,money); 
    }
}

1.7整合Junit

  1. 让Junit通知spring加载配置文件
  2. 让spring容器自动进行注入
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext2.xml")
public class TestApp {

    @Autowired //与junit整合,不需要再spring xml设置扫描
    private AccountService accountService;
    @Test
    public void demo01(){
 applicationContext.getBean("accountService", AccountService.class);
        accountService.transfer("jack","rose",100);
    }
}

2.整合web

1.tomcat 启动加载配置文件

    servlet-->init(ServletConfig) --><Load-on-startup>2
    
    filter--> ServletContextListener --> servletContext 对象监听
    spring 提供监听器 ContextLoaderListener -->web.xml<listener><listener-class> ....
    如果只配置监听器,默认加载xml位置:/WEB-INF/applicationContext.xml
  1. 确定配置文件 文职,通过系统初始化参数
SercletContext 初始化参数web.xml
    <context-param>
    <param-name>contextConfigLocation
    <prarm-value>classpath:applicationContext.xml
 <!--确定配置文件位置-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    
    <!--配置spring 监听器 加载xml配置文件-->
    <listener>
        <listener-class>org.springframework.web.context.ContextCleanupListener</listener-class>
    </listener>
上一篇 下一篇

猜你喜欢

热点阅读