Spring学习(四)Jdbc连接池交个spring管理和事务操作

一、连接池的配置交给Spring管理

1,添加jar包

这里写图片描述

2,spring的jdbc连接池配置



<!-- 配置连接池 -->
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="password" value="tianyejun" />
        <property name="username" value="root" />
        <property name="url" value="jdbc:mysql:///springday3" />
    </bean>
    <!-- 配置jdbc的模板类 -->
    <bean id="JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>

    </bean>

3,测试类


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")

public class Demo1 {

/**
     * 使用ioc的方式
     */
    @Resource(name = "JdbcTemplate")
    private JdbcTemplate JdbcTemplate;

    @Test
    public void run2() {
        // 可以实现对数据库的cud
        JdbcTemplate.update("insert into t_account values(null,?,?)", "3343", "1000");
    }

    /**
     * 数据库查询
     */
    @Test
    public void runQuery() {
        //查询一条数据
        AccontBean bean =JdbcTemplate.queryForObject("select * from t_account where id=?", new String[] { "1" },
                new MyrowMapper());
        System.out.println(bean.toString());
        // 查询所有数据
        List<AccontBean> list = (List<AccontBean>) JdbcTemplate.query("select * from t_account",new MyrowMapper());
        System.out.println(list);
    }

    public class MyrowMapper implements RowMapper<AccontBean> {

        @Override
        public AccontBean mapRow(ResultSet rs, int rowNum) throws SQLException {
            AccontBean bean = new AccontBean();
            bean.setName(rs.getString(2));
            bean.setPrice(rs.getInt(3));
            return bean;
        }

    }
 }
}

二、Spring的事物管理

1,事物的特性

原子性 :强调事务的不可分割.
一致性 :事务的执行的前后数据的完整性保持一致.
隔离性 :一个事务执行的过程中,不应该受到其他事务的干扰
持久性 :事务一旦结束,数据就持久到数据库

2,事物的传播行为

PROPAGION_XXX :事务的传播行为

  • 保证同一个事务中

PROPAGATION_REQUIRED:支持当前事务,如果不存在 就新建一个(默认)
PROPAGATION_SUPPORTS:支持当前事务,如果不存在,就不使用事务
PROPAGATION_MANDATORY:支持当前事务,如果不存在,抛出异常

  • 保证没有在同一个事务中

PROPAGATION_REQUIRES_NEW: 如果有事务存在,挂起当前事务,创建一个新的事务
PROPAGATION_NOT_SUPPORTED :以非事务方式运行,如果有事务存在,挂起当前事务
PROPAGATION_NEVER : 以非事务方式运行,如果有事务存在,抛出异常

PROPAGATION_NESTED: 如果当前事务存在,则嵌套事务执行

案例:模拟银行转账漏洞环境

(1)创建业务层


业务层接口类:
public interface AccountServiceInter {
    public void pay(String out, String in, double money);

}

业务层接口实现类

public class AccountServiceImp implements AccountServiceInter {
    private AccountDaoInter acountdao;

    /**
     * 转账的方法
     */
    @Override
    public void pay(String out, String in, double money) {
        // 先价钱
        getAcountdao().outMoney(out, money);
        /**
         *这里人为制造一个异常,造成转账出现异常
        */
        int a=10/0;

        // 后加钱
        getAcountdao().inMoney(in, money);
    }

    public AccountDaoInter getAcountdao() {
        return acountdao;
    }

    public void setAcountdao(AccountDaoInter acountdao) {
        this.acountdao = acountdao;
    }

}

(2)创建dao层


dao接口类

public interface AccountDaoInter {
    // 扣钱
    public void outMoney(String out, double money);

    // 加钱
    public void inMoney(String in, double money);

}

dao接口实现类

public class AccountDaoImp extends JdbcDaoSupport implements AccountDaoInter {

    /**
     * 扣钱
     */
    @Override
    public void outMoney(String out, double money) {
        int update = this.getJdbcTemplate().update("update t_account set money=(money-?) where id=?", money, out);
        System.out.println("fdafd" + update);
    }

    /**
     * 加钱
     */
    @Override
    public void inMoney(String in, double money) {
        int update = this.getJdbcTemplate().update("update t_account set money=(money+?) where id=?", money, in);
        System.out.println("fdafd" + update);
    }

}

(3)spring中配置业务层和dao


<!-- 配置连接池 -->
<bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="password" value="tianyejun6" />
    <property name="username" value="root" />
    <property name="url" value="jdbc:mysql:///springday3" />
</bean>


<!-- service业务层 -->

<bean id="accountService"     class="com.itcast.test1.AccountServiceImp">
    <property name="acountdao" ref="accountDaoImp"></property>
</bean>

<!-- 持久层dao -->

<bean id="accountDaoImp" class="com.itcast.test1.AccountDaoImp">
    <property name="dataSource" ref="dataSource" />
</bean>

(4)编写测试类


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test1 {
    @Resource(name = "accountService")
    private AccountServiceInter accountService;
    DataSourceTransactionManager a;
    @Test
    public void run1() {
        accountService.pay("1", "3", 100);
    }

}

总结:上面转账过程如果出现异常情况,就会造成转账漏洞,所以采用下面AOP转账方式

三、spring事务管理采用AOP方式

1,引入jar包

这里写图片描述

2,配置事务管理器 ,开启事物注解


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

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

3,配置事务的通知


<!-- 2,配置通知 -->
<tx:advice id="myAdvice" transaction-manager="transactionManager">
    <tx:attributes>
     <!-- 
        isolation="DEFAULT"     隔离级别
        propagation="REQUIRED"  传播行为
        read-only="false"   只读
        timeout="-1"        过期时间
        rollback-for=""     -Exception
        no-rollback-for=""  +Exception
    -->
        <tx:method name="pay" propagation="REQUIRED" />
    </tx:attributes>
</tx:advice>

4,配置AOP


<!--
配置AOP:如果是自己编写的aop使用<aop:aspect>;
如果使用spring框架提供的通知使用<aop:advisor/>
 -->
<aop:config>
    <aop:advisor advice-ref="myAdvice"
        pointcut="execution(public * com.itcast.test2.AccountServiceImp.pay(..))"/>
</aop:config>

5,实现代码

(1)业务层

业务层接口

public interface AccountServiceInter {
    public void pay(String out, String in, double money);

}


业务层接口实现类

/**
 * 
 *@Transactional 添加到类上,该类所有的方法都有事务
 */
@Transactional
public class AccountServiceImp implements AccountServiceInter {
    private AccountDaoInter acountdao;

    /**
     * 转账的方法
     */
    @Override
    @Transactional
    public void pay(String out, String in, double money) {
        // 先价钱
        getAcountdao().outMoney(out, money);
//      int a=10/0;
        // 后加钱
        getAcountdao().inMoney(in, money);
    }

    public AccountDaoInter getAcountdao() {
        return acountdao;
    }

    public void setAcountdao(AccountDaoInter acountdao) {
        this.acountdao = acountdao;
    }

}

(2)dao层


dao接口类

public interface AccountDaoInter {
    // 扣钱
    public void outMoney(String out, double money);

    // 加钱
    public void inMoney(String in, double money);

}

dao实现接口类


public class AccountDaoImp extends JdbcDaoSupport implements AccountDaoInter {

    /**
     * 扣钱
     */
    @Override
    public void outMoney(String out, double money) {
        int update = this.getJdbcTemplate().update
        ("update t_account set money=(money-?) where id=?", money, out);
        System.out.println("fdafd" + update);
    }

    /**
     * 加钱
     */
    @Override
    public void inMoney(String in, double money) {
update("update t_account set money=(money+?) where id=?", money, in);
        System.out.println("fdafd" + update);
    }

}

(3)Spring的xml配置


<!-- 配置连接池 -->
<bean id="dataSource"       class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="password" value="tianyejun6" />
    <property name="username" value="root" />
    <property name="url" value="jdbc:mysql:///springday3" />
</bean>

<!-- service业务层 -->

<bean id="accountService" class="com.itcast.test2.AccountServiceImp">
    <property name="acountdao" ref="accountDaoImp"></property>
</bean>

<!-- 持久层dao -->

<bean id="accountDaoImp" class="com.itcast.test2.AccountDaoImp">
    <property name="dataSource" ref="dataSource" />
</bean>

<!-- 1,配置平台事物管理器 -->

<bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<!-- 声明式事物 -->
<!-- 2,配置通知 -->

<tx:advice id="myAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="pay" propagation="REQUIRED" />
    </tx:attributes>
</tx:advice>

<!--

配置AOP:如果是自己编写的aop使用<aop:aspect>;
如果使用spring框架提供的通知使用<aop:advisor/>

 -->

<aop:config>
  <aop:advisor advice-ref="myAdvice"
        pointcut="execution(public * com.itcast.test2.AccountServiceImp.pay(..))"/>
</aop:config>

(4)测试类


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class Test1 {
    @Resource(name = "accountService")
    private AccountServiceInter accountService;
    DataSourceTransactionManager a;
    @Test
    public void run1() {
        accountService.pay("1", "3", 100);
    }

}

(5)源码

下载地址: http://download.csdn.net/detail/tianyejun6/9795910

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值