Spring > 纯注解方式配置spring声明事事务

1 》首先pom文件导入所需依赖

< 这里面是注释 , CSDN自己的注释看不清>

<?xml version="1.0" encoding="UTF-8"?>
<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>com.anno</groupId>
    <artifactId>spring_anno_dome</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.26</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.7</version>
        </dependency>
    </dependencies>
</project>

2 》编写DriverMangerDataSource所需要的jdbcConfig.properties

jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://159.75.xxx.xxx:2207/dome02?characterEncoding=utf8
jdbc.username = root
jdbc.password = xxxxxxxxxx

3 》编写需要用到的类

3.1 》 Dao层接口及其实现类

3.1.1 》 AccountDao接口

package com.anno.dao;

import com.anno.domain.Account;

import java.util.List;

public interface AccountDao {
    
    
    // find all account
    List<Account> findAllAccount();

    // find account by Id
    Account findAccountById(Integer Id);

    // update Account
    Integer updateAccount(Account account);

    // transfer source to target
    Integer updateSourceToTarget(Account source , Account target , Float transferMoney);
}

3.1.2 》 AccountDao接口实现类

package com.anno.dao.impl;

import com.anno.dao.AccountDao;
import com.anno.domain.Account;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;


@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {
    
    

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public List<Account> findAllAccount() {
    
    
        return jdbcTemplate.query("select * from account", new BeanPropertyRowMapper<Account>(Account.class));
    }

    @Override
    public Account findAccountById(Integer Id) {
    
    
        return jdbcTemplate.queryForObject("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class), Id);
    }

    @Override
    public Integer updateAccount(Account account) {
    
    
        /*
         * 一次判断account对象中那些属性存在 哪些属性不存在
         * */
        StringBuilder sb = new StringBuilder("update account set ");
        // 判断 account 对象是否为空
        if (account == null || account.getId() == null) {
    
    
            // 对象为空 抛出异常 触发事务,进行回滚操作
            System.out.println("Id is null ~");
            throw new RuntimeException("Execute Fail ~~ : by ID Field is null ~~");
        } else {
    
    
            // account不为空
            if (account.getName() == null) {
    
    
                // name is null ---- name值为空,输出提示
                System.out.println("Name is null ~");

                // 并且判断money是否为空
                if (account.getMoney() != null) {
    
    
                    // money value not null  ----  不为空,进行sql语句的拼接
                    System.out.println("Money is : " + account.getMoney());
                    sb.append("money = " + account.getMoney() + " ");
                } else {
    
    
                    // money value is null --- 当name,金额都为空时,抛出异常,触发回滚操作
                    System.out.println("Money is null ~");
                    throw new RuntimeException("Need's Values is null ~ \ncannot update ~ \nBy id is : " + account.getId());
                }
            } else {
    
    
                // name is not null 名字不为空 ,拼接sql
                System.out.println("Name is : " + account.getName());
                sb.append("name = '" + account.getName() + "' ");
                if (account.getMoney() != null) {
    
    
                    // money value not null 金额不为空,拼接字符串
                    System.out.println("Money is : " + account.getMoney());
                    sb.append(", money = " + account.getMoney() + " ");
                } else {
    
    
                    // money value is null
                    System.out.println("Money is null ~");
                }

            }
            // 拼接为哪个id更新
            sb.append("where id = " + account.getId());
            String sql_update = sb.toString();
            System.out.println("SQL is : " + sql_update);
            int i = 0;
            i = jdbcTemplate.update(sql_update); // 返回更新的行数
            return i;
        }
    }

    @Override
    public Integer updateSourceToTarget(Account source, Account target, Float transferMoney) {
    
    
        // update line
        Integer update_line_number = 0;

        // 判断id是否为空
        if (source.getId() != null && target.getId() != null) {
    
    
            // 判断数据库中是否有这两个用户
            source = findAccountById(source.getId());
            target = findAccountById(target.getId());
            if (source!=null && target!=null){
    
    
                source.setMoney(source.getMoney() - transferMoney);
                target.setMoney(target.getMoney() + transferMoney);
                // 更新账户信息
                update_line_number += updateAccount(source);
                update_line_number += updateAccount(target);
            }else {
    
    
                // 获取到的数据有一方为空
                throw new RuntimeException("请检查转账所需的id是否正确 ~~");
            }
        }else {
    
    
            // id值为空
            throw new RuntimeException("请设置转账所需的id ~~");
        }
        return update_line_number;
    }
}

3.2 》 Service层接口及其实现类

3.2.1 AccountService接口

package com.anno.service;

import com.anno.domain.Account;

import java.util.List;

public interface AccountService {
    
    
    // find all account
    List<Account> findAllAccount();

    // find account by Id
    Account findAccountById(Integer Id);

    // update Account
    Integer updateAccount(Account account);

    // transfer source to target
    Integer updateSourceToTarget(Account source , Account target , Float transferMoney);

}

3.2.2 AccountServiceImpl实现类

package com.anno.service.impl;

import com.anno.dao.AccountDao;
import com.anno.domain.Account;
import com.anno.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service("accountService")
public class AccountServiceImpl implements AccountService {
    
    

    @Autowired
    @Qualifier("accountDao")
    private AccountDao accountDao;

    @Override
    @Transactional(propagation= Propagation.SUPPORTS,readOnly=true)
    public List<Account> findAllAccount() {
    
    
        return accountDao.findAllAccount();
    }

    @Override
    @Transactional(propagation= Propagation.SUPPORTS,readOnly=true)
    public Account findAccountById(Integer Id) {
    
    
        return null;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED , readOnly = false)
    public Integer updateAccount(Account account) {
    
    
        return null;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED , readOnly = false)
    public Integer updateSourceToTarget(Account source, Account target, Float transferMoney) {
    
    
        Integer integer = 0;

        integer = accountDao.updateSourceToTarget(source, target, transferMoney);
        int i = 1 / 0;
        System.out.println(accountDao.findAccountById(source.getId()));
        System.out.println(accountDao.findAccountById(target.getId()));

        if (integer == 2) return integer;
        else return null;
    }
}

3.3.3 》不重要的账户类

package com.anno.domain;

public class Account {
    
    
    private Integer id;
    private String name;
    private Float money;

    public Integer getId() {
    
    
        return id;
    }

    public void setId(Integer id) {
    
    
        this.id = id;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public Float getMoney() {
    
    
        return money;
    }

    public void setMoney(Float money) {
    
    
        this.money = money;
    }

    @Override
    public String toString() {
    
    
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}

4 》编写配置类

4.1 编写SpringConfiguration配置类

package com.anno.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration < 声明这是一个配置类,千万不要写成Component >
@ComponentScan({
    
    "com.anno.dao","com.anno.service"}) < 配置需要扫描的包 >
@Import({
    
    JdbcTemplateUtils.class,TransactionUtils.class}) < 配置需要导入的配置类 >
@PropertySource("jdbcConfig.properties")
@EnableTransactionManagement
public class SpringConfiguration {
    
    
}

4.2 编写JdbcTemplate配置类

package com.anno.config;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;

/*
Jdbc配置类
 */
public class JdbcTemplateUtils {
    
    

    @Value("${jdbc.driver}")
    private String driver;

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

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

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

    @Bean("jdbcTemplate")
    public JdbcTemplate getJdbcTemplate(@Qualifier("dataSource") DataSource dataSource){
    
    
        return new JdbcTemplate(dataSource);
    }

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

4.3 编写TransactionUtils 配置类

package com.anno.config;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

@Component
public class TransactionUtils {
    
    

    @Bean("transactionManger")
    public PlatformTransactionManager getDataSourceTransactionManager(@Qualifier("dataSource") DataSource dataSource){
    
    
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource);
        return dataSourceTransactionManager;
    }	
}

5 》编写测试类

package com.anno.text;

import com.anno.config.SpringConfiguration;
import com.anno.domain.Account;
import com.anno.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class Test_01 {
    
    
    @Autowired
    @Qualifier("accountService")
    private AccountService accountService;

    @Test
    public void method_01(){
    
    
        accountService.findAllAccount().forEach(System.out::println);
    }
    @Test
    public void method_02(){
    
    
        Account source = new Account();
        source.setId(1);
        Account target = new Account();
        target.setId(10);
        accountService.updateSourceToTarget(source,target,100f);
    }
}

5.1 》 测试

5.1.2 》数据库

在这里插入图片描述

5.1.3 》执行结果(无异常)

在这里插入图片描述

5.1.4 》执行结果(有异常)

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43309893/article/details/119787406