该项目模仿银行转账系统,一方money增加,另一方money减少,如果交易过程中出现异常,则取消本次交易,双方money都不变。AOP添加代码如果有任一方monry<0,则不能进行交易。
数据库的链接用到了jdbcTemplate.
数据库表如下
id | 1 | 2 |
username | lucy | mary |
money | 1000 | 1000 |
项目结构:
项目所需要的依赖:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.13</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.11.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.12.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
实体类:
public class account {
private String id;
private String username;
private int money;
public account() {
}
public account(String id, String username, int money) {
this.id = id;
this.money = money;
this.username = username;
}
public String getId() {
return id;
}
public void setMoney(int money) {
this.money = money;
}
public void setId(String id) {
this.id = id;
}
public int getMoney() {
return money;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsername() {
return username;
}
@Override
public String toString() {
return "account{" +
"id='" + id + '\'' +
", username='" + username + '\'' +
", money=" + money +
'}';
}
}
DAO层接口及接口实现类:
//接口
public interface accountDao {
public int addmoney(String username, int money);
public int jianshaomoney(String username, int money);
public int selectmoney(String username);
}
//接口实现类
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class accountDaoImpl implements accountDao {
private JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public int addmoney(String username, int money) {
String sql = "update t_account set money=money-? where username=? and money>0";
int num = jdbcTemplate.update(sql, money, username);
return num;
}
@Override
public int jianshaomoney(String username, int money) {
String sql = "update t_account set money=money+? where username=? and money>0";
int num = jdbcTemplate.update(sql, money, username);
return num;
}
@Override
public int selectmoney(String username) {
StringBuilder sb = newStringBuilder().insert(0,"'").append(username).append("'");
String sql="select money from t_account where username="+sb;
Integer num = jdbcTemplate.queryForObject(sql, Integer.class)
return num;
}
}
service层(添加事务管理):
import com.spring.Dao.accountDaoImpl;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Component
public class service {
private accountDaoImpl accountDao;
public accountDaoImpl getAccountDao() {
return accountDao;
}
public void setAccountDao(accountDaoImpl accountDao) {
this.accountDao = accountDao;
}
public boolean select (String username1, String username2) {
int num1 = accountDao.selectmoney(username1);
int num2 = accountDao.selectmoney(username2);
return num1 > 0 && num2 > 0;
}
//用注解的方法开启事务管理
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ)
public boolean zhuangzhang(String username1, String username2, int money) {
try {
int num1 = accountDao.addmoney(username1, money);
// int a = 10 / 0;
int num2 = accountDao.jianshaomoney(username2, money);
return num1 != 0 && num2 != 0;
} catch (Exception e) {
System.out.println("出现异常");
return false;
}
}
}
业务逻辑层(使用AOP):
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
public class accountadd {
private com.spring.service.service service;
public void setService(com.spring.service.service service) {
this.service = service;
}
public com.spring.service.service getService() {
return service;
}
@Pointcut(value = "execution(public* com.spring.service.service.*.*(..))")
public void add() {
}
//切入点有参数,需要注意参数的传入方法
@Before(value = "add()")
public boolean addaccount(String username1, String username2, int money) {
boolean bool = service.select(username1, username2);
boolean b = false;
if (bool) {
b = service.zhuangzhang(username1, username2, money);
}
return b;
}
}
配置文件:bean.xml
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="username" value="root"/>
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<!--mybatis是我的数据库名称 -->
<property name="password" value="123456"/>
</bean>
<bean id="accountDao" class="com.spring.Dao.accountDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
<bean id="service" class="com.spring.service.service">
<property name="accountDao" ref="accountDao"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="accountadd" class="com.spring.add.accountadd">
<property name="service" ref="service"/>
</bean>
<!--开启事务管理 -->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 开启事务注解-->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
<!--生成代理对象 -->
<aop:aspectj-autoproxy/>
</beans>
测试类:
import com.spring.add.accountadd;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
@Controller
public class test {
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
accountadd accountadd = applicationContext.getBean("accountadd", accountadd.class);
String username1 = "lucy";
String username2 = "mary";
int money = 100;
boolean b = accountadd.addaccount(username1, username2, money);
if (b) {
System.out.println("成功");
} else {
System.out.println("失败");
}
}
}
该项目我写到了测试方法,有需要也可以java web