使用Spring 完成转账业务添加日志功能

发布于:2024-04-25 ⋅ 阅读:(28) ⋅ 点赞:(0)

(完整的代码在文章附带文件中 , 文章里的代码仅作展示 , 可能有部分不完善
代码地址 :下载:https://javazhang.lanzn.com/i5oLI1vyiile 密码:1234
)
任务目标
在这里插入图片描述
具体实现方法和心得

步骤1. 导入依赖项
		Spring依赖 , aop依赖,德鲁伊依赖,mybatis依赖 , 
		mysql驱动 , mybatis-spring 依赖
		
注意点 mybatis-spring 和 mybatis 的依赖版本有
关联关系 , 需要注意
<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>spring-Demo1</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>spring-Demo1 Maven Webapp</name>
  <url>http://maven.apache.org</url>

  <dependencies>
<!-- Spring依赖   -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.10.RELEASE</version>
    </dependency>
<!--  aop依赖  -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.4</version>
    </dependency>
<!--  德鲁伊依赖  -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.16</version>
    </dependency>
<!--mybatis依赖  -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.6</version>
    </dependency>
<!--mysql驱动  -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.47</version>
    </dependency>
<!--    mybatis整合spring  和mybais是关联的 属于mybatis的pro   -->
      <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis-spring</artifactId>
          <version>1.3.0</version>
      </dependency>
      <!-- 测试框架依赖   -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>5.2.10.RELEASE</version>
          <scope>compile</scope>
      </dependency>

      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>5.2.10.RELEASE</version>
      </dependency>
  </dependencies>
  <build>
    <finalName>spring-Demo1</finalName>
  </build>
</project>


步骤2.
编辑Spring配置类 , Jdbc配置类 , Mybatis配置类

package com.zhang.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.stereotype.Controller;

@Configuration
@ComponentScan("com.zhang")
@PropertySource("classpath:jdbc.properties")
@Import({MyBatisConfig.class , JdbcConfig.class})
@EnableTransactionManagement
public class SpringConfig {
}

package com.zhang.config;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;

import javax.sql.DataSource;

public class MyBatisConfig {

    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
        SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
        ssfb.setTypeAliasesPackage("com.zhang.domain");
        ssfb.setDataSource(dataSource);
        return ssfb;
    }

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        msc.setBasePackage("com.zhang.dao");
        return msc;

    }
}
		心得Mybatis的两个关联路径操作 如果路径错误 ,会导致后面Service无法自动装配
package com.zhang.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;


public class JdbcConfig {

    @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
    public DataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        return ds;
    }
        @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource){
        DataSourceTransactionManager ptm = new DataSourceTransactionManager();
        ptm.setDataSource(dataSource);
        return ptm;
    }
}

}

心得 
	MybatisConfig的 MapperScannerConfigurer 方法
	是对数据举行处理代码的绑定
	SqlSessionFactoryBean 方法是对 数据库中的数据部分
	代码进行绑定

步骤三:编写数据操作AccountDao 和 日志操作 LogDao

package com.zhang.dao;

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;

public interface AccountDao {

    @Update("update tbl_account set money = money + #{money} where name = #{name}")
    void inMoney(@Param("name") String name ,@Param("money") Double money);

    @Update("update tbl_account set money = money - #{money} where name = #{name}")
    void outMoney(@Param("name") String name , @Param("money") Double money);

}

package com.zhang.dao;

import org.apache.ibatis.annotations.Insert;

public interface LogDao {

    @Insert("insert into tbl_log (info, createDate) values(#{info},now())")
    void log(@Param("info")String info);
}

	心得 : 在LogDao中 Insert 语句用到了一个now() 方法用于在数据库中添加当前时间

步骤四:编写domain包账户方法

package com.itheima.domain;

import java.io.Serializable;

public class Account implements Serializable {

    private Integer id;
    private String name;
    private Double 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 Double getMoney() {
        return money;
    }

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

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

步骤五 编写服务层Service , logService 和AccountService
这里用到事务的知识点 , 事务为了保证在程序出现错误时,回滚操作,防止出现更大错误 , 而数据库日志需要在数据库操作有错误时也要执行,不需要回滚 ,所以他的事务要和数据库操作的事务分开 , 分为两个事务

package com.zhang.service;

import org.apache.ibatis.annotations.Update;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

public interface LogService {

@Transactional(propagation = Propagation.REQUIRES_NEW)

    void log(String out , String in ,Double money);

}

package com.zhang.service;

import org.springframework.transaction.annotation.Transactional;

public interface AccountService {

    @Transactional
void transfer(String out , String in ,Double money);
}

package com.zhang.service.imp;

import com.zhang.dao.AccountDao;
import com.zhang.service.AccountService;
import com.zhang.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class AccountServiceImp implements AccountService {

    @Autowired
    private AccountDao accountDao;

    @Autowired
    private LogService logService;

    public void transfer(String out, String in, Double money) {

        try {
            accountDao.outMoney(out, money);
            accountDao.inMoney(in, money);
        } finally {
            logService.log(out, in, money);
        }


    }
}

package com.zhang.service.imp;

import com.zhang.dao.LogDao;
import com.zhang.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service

public class LogServiceImp implements LogService {
    @Autowired
    private LogDao logDao;

    public void log(String out, String in, Double money) {
            logDao.log("转账操作由" + out +"到" + in + ",金额" + money);
    }
}

测试用例

package com.zhang.service;
import com.zhang.config.SpringConfig;
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;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTest {
    @Autowired
private AccountService accountService;

    @Test
public void testTransfer() {
        accountService.transfer("Tom" , "Jerry" , 50D);
    }
}