1、数据库准备
使用配置类配置数据源、模板、事务回滚
package cn.edu.aaa.utils; import java.beans.PropertyVetoException; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; //import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.ImportResource; import org.springframework.context.annotation.PropertySource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import com.mchange.v2.c3p0.ComboPooledDataSource; @Configuration @ComponentScan("cn.edu.aaa") @PropertySource("classpath:jdbc.properties") @EnableTransactionManagement //让事务注释@Transactional起作用 public class MyConfiguration { @Value("${driver}") private String driver; @Value("${url}") private String url; @Value("${user}") private String user; @Value("${password}") private String password; @Bean //数据源 public ComboPooledDataSource combopooledDataSource() throws PropertyVetoException { ComboPooledDataSource dataSource=new ComboPooledDataSource(); dataSource.setJdbcUrl(url); dataSource.setDriverClass(driver); dataSource.setUser("root"); dataSource.setPassword("root"); return dataSource; } //模板 @Bean public JdbcTemplate jdbcTemplate(@Autowired DataSource dataSource) { JdbcTemplate jdbcTemplate=new JdbcTemplate(); jdbcTemplate.setDataSource(dataSource); return jdbcTemplate; } //事务处理 @Bean public PlatformTransactionManager transactionManager(@Autowired DataSource dataSource) { DataSourceTransactionManager transactionManager=new DataSourceTransactionManager(); transactionManager.setDataSource(dataSource); return transactionManager; } }
2、创建DAO层
DAO层负责数据库操作。定义了金额操作的方法
(1)定义接口
package cn.edu.aaa.dao; public interface AccountDao { int addMoney(String aname,int money); }
(2)接口实现类
package cn.edu.aaa.dao.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import cn.edu.aaa.dao.AccountDao; @Repository("AccountDao")//声明这个类是一个Spring管理的bean,并且bean的名称为"AccountDao"。这样,其他Spring组件可以通过"AccountDao"这个名称来引用这个bean。 @Scope("singleton")//声明这个bean的作用域为单例。这意味着在整个Spring容器中,这个bean只有一个实例。 public class AccountDaoImpl implements AccountDao{ @Autowired //通过@Autowired注解,自动装配一个JdbcTemplate的实例 private JdbcTemplate jdbcTemplate; public int addMoney(String aname, int money) { // TODO Auto-generated method stub int i=jdbcTemplate.update("update accounts set money=money+? where aname=?",money,aname);//执行一个SQL更新操作,返回更新的记录数 return i; } }
3、创建Service层
Service层是业务逻辑的核心。定义转账方法
(1)定义接口
package cn.edu.aaa.biz; public interface AccountBiz { boolean transfer(String aname1,String aname2,Integer money); }
(2)接口实现类。步骤:
1)转账方金额变少
2)收款方金额变多
3)转账过程中发生异常(事务回滚),输出false,数据表数据不变
package cn.edu.aaa.biz.impl; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.stereotype.Service; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; import org.springframework.transaction.support.DefaultTransactionDefinition; import cn.edu.aaa.biz.AccountBiz; import cn.edu.aaa.dao.AccountDao; @Service("AccountBiz") @Scope("singleton") public class AccountBizImpl implements AccountBiz{ @Autowired private AccountDao accountDao; @Transactional(isolation =Isolation.DEFAULT,propagation=Propagation.REQUIRED,readOnly=false) public boolean transfer(String aname1, String aname2, Integer money) { // TODO Auto-generated method stub try { accountDao.addMoney(aname1, (-1)*money); //System.out.println(1/0); //通过开放这句语句,来测试是否对异常处理 accountDao.addMoney(aname2, money); return true; }catch (Exception e) { TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//让事务只回滚 return false; } } }
4、测试转账功能
package cn.edu.aaa.test; import javax.annotation.Resource; import org.junit.Test; import org.junit.experimental.theories.suppliers.TestedOn; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.PropertySource; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import cn.edu.aaa.biz.AccountBiz; import cn.edu.aaa.utils.MyConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=MyConfiguration.class)//导入配置类 public class AccountBizTest { @Autowired private AccountBiz accountBiz; @Test public void test() { System.out.println(accountBiz.transfer("superman", "spiderman", 500)); } }
结果正常,输出true,数据表内容变化
结果异常,输出false,数据表内容不变
5、补充
pom.xml导入依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.edu.aaa</groupId> <artifactId>demo2</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.23</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.3.23</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.5</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.23</version> </dependency> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.27</version> </dependency> <dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version> </dependency> </dependencies> </project>
目录结构