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

news/2024/5/4 20:51:33

(完整的代码在文章附带文件中 , 文章里的代码仅作展示 , 可能有部分不完善
代码地址 :下载: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 {@Beanpublic SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();ssfb.setTypeAliasesPackage("com.zhang.domain");ssfb.setDataSource(dataSource);return ssfb;}@Beanpublic 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;@Beanpublic DataSource dataSource() {DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(username);ds.setPassword(password);return ds;}@Beanpublic 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;}@Overridepublic 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 {@Autowiredprivate AccountDao accountDao;@Autowiredprivate 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;@Servicepublic class LogServiceImp implements LogService {@Autowiredprivate 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);}
}

http://www.mrgr.cn/p/47637054

相关文章

openlayers 入门教程(六):controls 篇

目录 一、常用的控件 二、使用控件方法 三、添加删除control 的基本方法 四、control示例 1 比例尺 - ScaleLine 2 鹰眼/缩小图 - OverviewMap 3 全屏 - FullScreen 4 版权信息 - Attribution 5 旋转地图 - Rotate 6 放大缩小 - Zoom 7 缩放滑块控件 - ZoomSlider …

JavaEE 初阶篇-深入了解网络通信相关的基本概念(三次握手建立连接、四次挥手断开连接)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 网络通信概述 1.1 基本的通信架构 2.0 网络通信三要素 3.0 网络通信三要素 - IP 地址 3.1 查询 IP 地址 3.2 IP 地址由谁供应&#xff1f; 3.3 IP 域名 3.4 IP 分…

可视化大屏的应用(15):智慧城市中的十大价值

可视化大屏在智慧城市领域的十大应用价值如下&#xff1a; 实时数据监控&#xff1a; 可视化大屏可以将城市各种实时数据&#xff0c;如交通流量、环境监测、能源消耗等数据&#xff0c;以图表、地图等形式展示&#xff0c;帮助城市管理者实时监控城市运行状况。 智慧交通管理…

下载安装Gradle

一、下载Gradle1.Gradle官方下载地址:https://gradle.org/releases/2.下载之后进行解压二、配置环境变量我的电脑->属性->高级系统设置->环境变量在path里面添加:%GRADLE_HOME%\bin 三、验证是否安装成功打开CMD,输入gradle -v,此时会显示Gradle的版本号,这说明前…

idea启动jsp项目

idea启动jsp项目 1、idea打开jsp项目:2、项目配置:3、项目启动~~~~~~~~~~~~~~~~~~~~~over~~~~~~~~~~~~~~~~

贪心算法练习day.4

860.柠檬水找零 链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 在柠檬水摊上&#xff0c;每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品&#xff0c;&#xff08;按账单 bills 支付的顺序&#xff09;一次购买一杯。 每位顾客只买一…

JAVASE基础语法(异常、常用类)

一、异常 1.1 什么是异常 异常就是指不正常。是指代码在运行过程中可能发生错误&#xff0c;导致程序无法正常运行。 package com.atguigu.exception;public class TestException {public static void main(String[] args) {int[] arr {1,2,3,4,5};System.out.println(&quo…

js逆向实战之莫莫铺子sign参数解密

url: http://mmpz.ttzhuijuba.com/?r=/l&cids=1&site=classify&sort=0 分析过程抓取流量包。主要关注图中框起来这条流量包,因为这条流量包返回的是当前页面数据。该流量包的url地址有个加密的参数sign,目的就是找到sign参数的加密过程。按照常规思路会去搜索ur…

记一次new ArrayList导致的cpu飙升问题排查

参考:https://mp.weixin.qq.com/s/8JDPOAvmKYP8JZxau45hdw前言当时场景正常的jvm监控曲线图产生问题的jvm监控曲线图具体分析结束语昨天线上容器突然cpu飙升,也是第一次排查这种问题所以记录一下~ 前言 首先问题是这样的,周五正在写文档,突然收到了线上报警,发现cpu占用达到…

Kafka 架构深入探索

目录 一、Kafka 工作流程及文件存储机制 二、数据可靠性保证 三 、数据一致性问题 3.1follower 故障 3.2leader 故障 四、ack 应答机制 五、部署FilebeatKafkaELK 5.1环境准备 5.2部署ELK 5.2.1部署 Elasticsearch 软件 5.2.1.1修改elasticsearch主配置文件 5.2…

安卓APP脱壳的本质以及如何快速发现ART下的脱壳点

参考:https://bbs.kanxue.com/thread-254555.htm拨云见日:安卓APP脱壳的本质以及如何快速发现ART下的脱壳点我在文章《FART:ART环境下基于主动调用的自动化脱壳方案》中简单对当前的几个脱壳方法进行了总结,然而并没有对每一种的具体原理进行分析。同时,在文章《FART正餐前…

力扣HOT100 - 114. 二叉树展开为链表

解题思路&#xff1a; class Solution {List<TreeNode> list new ArrayList<>();public void flatten(TreeNode root) {recur(root);for (int i 1; i < list.size(); i) {TreeNode pre list.get(i - 1);TreeNode cur list.get(i);pre.left null;pre.right…

冰达ROS机器人快速使用指南

欢迎来到《冰达ROS机器人极简使用指南》 Q&#xff1a;这份教程适合谁&#xff1f; A&#xff1a;适合完全0基础新手&#xff0c;需要快速跑起来机器人的基本功能。也适合技术大佬需要快速的了解冰达ROS机器人的使用方法。 Q&#xff1a;这份教程内容很少&#xff0c;是不是…

百度的代码,Comate写了27%。诚邀你来测评,获取丰厚好礼!

4月16日,在Create 2024百度AI开发者大会上发表的《人人都是开发者》主题演讲中,李彦宏指出: “百度每天新增的代码中,已经有27%是由Comate生成的。” 是的!Comate被老板表扬啦!Baidu Comate智能代码助手,和百度的工程师们共同完成了27%的代码! 而现在,Comate还走入了喜…

图表开发控件JointJS携全新4.0版本助力轻量开发

JointJS 和JointJS的v4.0版本正式发布&#xff0c;作为图表库的首个无依赖版本&#xff0c;备受期待&#xff01;新版本经过精心打磨&#xff0c;摆脱了jQuery、Backbone和Lodash的依赖&#xff0c;使得库更加精简且核心功能不变。此次慧都与JointJS厂商合作&#xff0c;携手带…

6. JSP详解

1. 什么是JSP 全称为:Java Server Pages Java服务器端页面,也和Serlvet一样,用于动态Web技术!JSP中的内容就是html,但是能够嵌套java语言 HTML只给用户提供静态数据2. JSP原理服务器内部工作 tomcat中有一个work目录 IDEA中使用Tomcat的会在IDEA的tomcat中生产一个work目录…

【计算机网络】MAC地址简介

MAC&#xff08;Medium Access Control&#xff09;&#xff0c;即媒介访问控制&#xff0c;是计算机网络通信中的重要概念。每个NIC&#xff08;Network Interface Card&#xff09;&#xff0c;即网络适配器&#xff0c;都具有独自且不变的MAC地址&#xff08;烧录的&#xf…

vis.js关系图

代码案例<!DOCTYPE html> <html lang="en"><head><title>Network</title><scripttype="text/javascript"src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script><styl…