Spring AOP实战 纯注解方式实现事务管理

一、启动类

package com.springlearning.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@ComponentScan({"com.springlearning"})
@Import(DBConfiguration.class)
@PropertySource("classpath:application.yml")
public class SpringConfiguration {

}

二、Datasource配置类

public class DBConfiguration {

    @Value("${driverClassName}")
    private String driverClassName;

    @Value("${url}")
    private String url;

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;


    @Bean("dataSource")
    public DataSource getDataSource(){
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);

        return dataSource;
    }
}

三、Dao类

@Repository
public class AccountDaoImpl implements IAccountDao {

    @Autowired
    ConnectionUtils connectionUtils;

    //保存
    public void saveAccount(Account account){
        PreparedStatement pstmt = null;
        String saveSql = "insert into accounts(id, name, money) value(?,?,?)";
        try {
            pstmt = connectionUtils.getConnection().prepareStatement(saveSql);
            pstmt.setInt(1, account.getId());
            pstmt.setString(2, account.getName());
            pstmt.setFloat(3, account.getMoney());
            pstmt.execute();
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }

    //删除
    public void deleteAccount(int id){
        PreparedStatement pstmt = null;
        String deleteSql = "delete from accounts where id = ?";
        try {
            pstmt = connectionUtils.getConnection().prepareStatement(deleteSql);
            pstmt.setInt(1, id);
            pstmt.execute();
        } catch (SQLException e) {
            e.printStackTrace();
        }


    }

    //更新
    public void updateAccount(Account account){
        PreparedStatement pstmt = null;
        String updateSql = "update accounts set money = ? where id = ?";
        try {
            pstmt = connectionUtils.getConnection().prepareStatement(updateSql);
            pstmt.setFloat(1, account.getMoney());
            pstmt.setInt(2, account.getId());
            pstmt.execute();
        } catch (SQLException e) {
            e.printStackTrace();
        }


    }

    //查询多个
    public List<Account> searchAccounts(float money){
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<Account> accountList = new ArrayList<Account>();
        String serchAccountsSql = "select * from accounts where money > ?";
        RowMapper<Account> rowMapper = new BeanPropertyRowMapper<Account>(Account.class);
        try {
            pstmt = connectionUtils.getConnection().prepareStatement(serchAccountsSql);
            pstmt.setFloat(1, money);
            rs = pstmt.executeQuery();
            while(rs.next()){
                Account account = new Account();
                account.setId(rs.getInt(1));
                account.setName(rs.getString(2));
                account.setMoney(rs.getFloat(3));
                accountList.add(account);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return accountList;
    }


    //查询一个
    public Account searchAccountByName(String name){
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        Account account = new Account();
        String searchAccountByName = "select * from accounts where name = ?";
        try {
            pstmt = connectionUtils.getConnection().prepareStatement(searchAccountByName);
            pstmt.setString(1, name);
            rs = pstmt.executeQuery();
            if(rs.next()){
                account.setId(rs.getInt(1));
                account.setName(rs.getString(2));
                account.setMoney(rs.getFloat(3));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return account;
    }

    //查询一行或一列
    public Integer serchCount(float money){
        PreparedStatement pstmt = null;
        int count = 0;
        String searchCount = "select count(*) from accounts where money > ?";
        try {
            pstmt = connectionUtils.getConnection().prepareStatement(searchCount);
            pstmt.setFloat(1, money);
            ResultSet rs = pstmt.executeQuery();
            if(rs.next()){
                count = rs.getInt(1);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return count;
    }

    public void transfer(String sourceName, String targetName, float money){
        Account source = searchAccountByName(sourceName);
        Account target = searchAccountByName(targetName);
        source.setMoney(source.getMoney() - money);
        target.setMoney(target.getMoney() + money);
        updateAccount(source);
         int i = 1/0;
        updateAccount(target);
    }

}

四、Service实现类

@Service
public class AccountServiceImpl implements IAccountService {

    @Autowired
    IAccountDao accountDao;

    public void saveAccount(Account account) throws SQLException {
        accountDao.saveAccount(account);
    }

    public void deleteAccount(int id)  throws SQLException {
        accountDao.deleteAccount(id);
    }

    public void updateAccount(Account account)  throws SQLException {
        accountDao.updateAccount(account);
    }

    public List<Account> searchAccounts(float money) throws SQLException  {
        return accountDao.searchAccounts(money);
    }

    public Account searchAccountByName(String name) throws SQLException  {
        return accountDao.searchAccountByName(name);
    }

    public Integer serchCount(float money)  throws SQLException {
        return accountDao.serchCount(money);
    }

    public void transfer(String sourceName, String targetName, float money)  throws SQLException {
        accountDao.transfer(sourceName, targetName, money);
    }
}

五、Connection

@Component
public class ConnectionUtils{

    ThreadLocal<Connection> tl = new ThreadLocal<Connection>();

    @Autowired
    DataSource dataSource;

    public Connection getConnection() {
        Connection conn = tl.get();
        if (conn == null) {
            try {
                conn = dataSource.getConnection();
                tl.set(conn);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        return conn;
    }

    public void remove() {
        //将connection移除,此时connection已经被关掉如果不从线程中移除connection,那么下次就会拿到带有无效connection的线程
        tl.remove();
    }
}

六、代理类

package com.springlearning.utils;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

import java.sql.SQLException;

@Component
@Aspect
//相当于
@EnableAspectJAutoProxy
public class TransactionManager {

    @Pointcut("execution(* *.*.*.*.AccountServiceImpl.*(..))")
    public void pt1(){}

    @Autowired
    ConnectionUtils connectionUtils;

//    @Before("pt1()")
    public void begainTransaction() {
        System.out.println("begainTransaction");
        try {
            connectionUtils.getConnection().setAutoCommit(false);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

//    @AfterReturning("pt1()")
    public void commitTransaction() {
        System.out.println("commitTransaction");
        try {
            connectionUtils.getConnection().commit();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

//    @AfterThrowing("pt1()")
    public void rollback() {
        System.out.println("rollback");
        try {
            connectionUtils.getConnection().rollback();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

   // @After("pt1()")
    public void close() {
        try {
            System.out.println("close connection");
            connectionUtils.getConnection().close();
            connectionUtils.remove();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


    @Around("pt1()")
    public Object aroundTransaction(ProceedingJoinPoint joinPoint){

        Object rtValue = null;
        Object[] args = joinPoint.getArgs();
        try {
            begainTransaction();
            rtValue = joinPoint.proceed(args);
            commitTransaction();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            rollback();
        }finally {
            close();
        }
        return rtValue;
    }
}

project目录:
Spring AOP实战 纯注解方式实现事务管理_第1张图片
测试类

package com.springlearning;

import com.springlearning.config.SpringConfiguration;
import com.springlearning.entity.Account;
import com.springlearning.service.IAccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.sql.SQLException;
import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class TestAccount {

    @Autowired
    IAccountService accountService;

    @Test
    public void testTransfer() throws SQLException {
        accountService.transfer("one", "two", 100);
    }

    @Test
    public void testSaveAccount() throws SQLException {
        Account account = new Account();
        account.setId(5);
        account.setName("five");
        account.setMoney(1000f);
        accountService.saveAccount(account);
    }

    @Test
    public void testDeleteAccount() throws SQLException {
        accountService.deleteAccount(5);
    }

    @Test
    public void updateAccount() throws SQLException {
        Account account = new Account();
        account.setId(1);
        account.setMoney(1000);
        accountService.updateAccount(account);
    }

    @Test
    public void searchAccounts() throws SQLException {
        List<Account> accountList = accountService.searchAccounts(100f);
        for (Account account : accountList) {
            System.out.println(account.toString());
        }
        System.out.println(accountList.size());
    }

    @Test
    public void searchAccountByName() throws SQLException {
        System.out.println(accountService.searchAccountByName("one").toString());
    }

    @Test
    public void serchCount() throws SQLException {
        System.out.println(accountService.serchCount(100f));
    }

}

你可能感兴趣的:(Spring AOP实战 纯注解方式实现事务管理)