以一个转账案例来复习:
一、案例前的知识需要:aop事务,
jdbc模板连接池之类的。
1.aop事务,面向切面编程思想。
<bean name="userService" class="cn.itcast.service.UserServiceImpl" ></bean>
这一行代码是我们要执行的主要操作,就是增删查改的实现类层,里面有操作的方法
<bean name="myAdvice" class="cn.itcast.d_springaop.MyAdvice" ></bean>
这一行代码是在执行相应的操作时反馈给用户的信息,类myAdvice代码在下面
<aop:config>
<!-- 配置切入点
public void cn.itcast.service.UserServiceImpl.save()
void cn.itcast.service.UserServiceImpl.save()
* cn.itcast.service.UserServiceImpl.save()
* cn.itcast.service.UserServiceImpl.*()
* cn.itcast.service.*ServiceImpl.*(..) 解释:这是接近实际开发的形式,表示在当前项目service包下所有以ServiceImpl结尾的类中的所有方法,(..)表示参数不限
* cn.itcast.service..*ServiceImpl.*(..)
-->
配置切入点id为pc
<aop:pointcut expression="execution(* cn.itcast.service.*ServiceImpl.*(..))" id="pc"/>
制定通知ref为前面的id “myAdvice” ,pointcut-ref=“pc” 切入点,id为前面定义好的pc
<aop:aspect ref="myAdvice" >
<!-- 指定名为before方法作为前置通知 -->
<aop:before method="before" pointcut-ref="pc" />
<!-- 后置 -->
<aop:after-returning method="afterReturning" pointcut-ref="pc" />
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pc" />
<!-- 异常拦截通知 -->
<aop:after-throwing method="afterException" pointcut-ref="pc"/>
<!-- 后置 -->
<aop:after method="after" pointcut-ref="pc"/>
</aop:aspect>
</aop:config>
2.jdbc模板连接池之类的。
db.properties里面的内容:
jdbc.jdbcUrl=jdbc:mysql:///mybatis
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.user=root
jdbc.password=12345
指定spring读取db.properyies配置注入带连接池当中
<context:property-placeholder location="classpath:db.properties"/>
1.连接池
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
连接池解释:bean文件里面的class是固定的,name一般起dataSource,
value里面的值采用${}的格式
Dao的相关代码
<bean name="accountDao" class="daoimpl.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--第2.Dao的类的具体代码>
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
@Override
public void increase(Integer id, Double money) {
super.getJdbcTemplate().update("update t_account set money=money+? where id=?", money,id);
}
@Override
public void decrease(Integer id, Double money) {
super.getJdbcTemplate().update("update t_account set money=money-? where id=?", money,id);
}
解释:如果Dao的实现类这一层继承了JdbcDaoSupport类的话,就可以不用写JDBCTemplate这一个对象了,
以前是采用JDBCTemplate jt来完成相应的操作,现在可以全部换成super.getJdbcTemplate()来调用增删查改的方法。
service
<bean name="accountService" class="service.AccountServiceImpl">
<property name="ad" ref="accountDao"></property>
<!-- <property name="tt" ref="transactionTemplate"></property>-->
</bean>
<!--3.service, AccountServiceImp的具体代码 -->
private AccountDao ad;
private TransactionTemplate tt;
@Override
@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false)
public void transfer(final Integer from, final Integer to, final Double money) {
ad.decrease(from, money);
ad.increase(to, money);
}
解释: private TransactionTemplate tt;这一行开启的是Transaction事务模板,具体xml文件配置如下:
<!-- 事务核心管理器,封装了所有事务操作. 依赖于连接池 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
<property name="dataSource" ref="dataSource" ></property>
</bean>
<!-- 事务模板对象 -->
<bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate" >
<property name="transactionManager" ref="transactionManager" ></property>
</bean>
而现在我们用的是aop注解事务来处理,配置文件中需要的代码:
<!-- 开启使用注解管理aop事务 -->
<tx:annotation-driven/>
在当前类方法transfer的前面,我们需要加一行注解: @Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false),达到用注解配置aop事务的目的。
二、整体思路整理:在本例转账中,我们先在Dao层创建AccountDao接口,中间定义两个抽象方法:
void increase(Integer id,Double money);
void decrease(Integer id,Double money);,然后在AccountDaoImpl中,继承JdbcDaoSupport,采用jdbc模板来来实现方法,钱的增加和减少。然后在service和serviceimpl中就是实现这一功能的方法:
transfer(final Integer from, final Integer to, final Double money)
然后我们在当前src下面建立一个xml文件来完成配置,创建db.properties的文件来填写数据库的配置,用代码:<context:property-placeholder location=“classpath:db.properties” />读取文件当中数据库的配置
然后完成连接池、Dao、Service的相关配置,最后通过:tx:annotation-driven/开启使用注解管理aop事务,最后在serviceimpl实现类前面加入: @Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false)来完成注解aop事务。
最后测试代码:
@RunWith(SpringJUnit4ClassRunner.class) //Junit测试的必须注解
@ContextConfiguration(“classpath:applicationContext.xml”) //制定xml配置文件的位置
public class Demo {
@Resource(name=“accountService”) //将配置文件中service层中的accountService注入到下面的as中
private AccountService as;
@Test
public void fun1(){
as.transfer(1, 2, 100d);
}