阅读本文前,请先学习完成我的上一篇文章。上一篇文章地址
IDEA搭建spring boot项目四:AOP+log4j打日志。_cunRenJi的博客-CSDN博客
目录
mybatis简介
一、添加依赖
二、建表
三、yml文件创建与配置
四、表对应实体类创建
五、数据库操作文件创建
六、持久层接口创建
七、数据库插入
八、插入数据库测试
九 、数据库更新
十、数据库更新测试
十一、数据库查询
mybatis简介
略
一、添加依赖
pom.xml中添加mybatis相关依赖并重载项目
此时的pom.xml文件内容
4.0.0 org.springframework.boot spring-boot-starter-parent2.6.3 com.jicr springbootTest0.0.1-SNAPSHOT springbootTest springbootTest 1.8 org.springframework.boot spring-boot-starter-weborg.springframework.boot spring-boot-starter-loggingorg.springframework.boot spring-boot-starter-testtest net.sf.json-lib json-libjdk15 2.4 org.projectlombok lomboktrue org.springframework.boot spring-boot-starter-aop2.6.2 org.apache.commons commons-lang33.12.0 org.springframework.boot spring-boot-starter-log4j22.6.2 javax.persistence persistence-api1.0.2 org.mybatis.spring.boot mybatis-spring-boot-starter2.2.1 mysql mysql-connector-java8.0.27 runtime com.alibaba druid1.2.8 org.springframework.boot spring-boot-maven-plugin
二、建表
创建mysql数据库表以备用
-- auto-generated definition
create table logs
(
seq varchar(50) not null comment '流水号'
primary key,
server_code varchar(20) not null comment '服务编码',
server_name varchar(100) null comment '服务名称',
head_req_date date null comment '请求日期',
head_req_time varchar(20) null comment '请求时间',
head_req_organ varchar(50) null comment '请求方名称',
req_content varchar(4000) null comment '请求报文',
head_rsp_date date null comment '响应日期',
head_rsp_time varchar(20) null comment '响应时间',
rsp_content varchar(4000) null comment '响应内容'
)
comment '日志存储表';
使用idea连接数据库(用navicat也行)
三、yml文件创建与配置
在resources目录下创建3个yml文件,分别在开发,测试,生产时使用
事实上这三个文件需要在项目开始创建application.yml文件时就创建,application.yml文件用来配置公共信息,其他3个文件配置不同环境所需不同的配置信息。
在application.yml文件中配置寻找对应环境的yml文件。
application.yml文件内容
# 数据源
spring:
profiles:
active: dev #通过设置此项来寻找对应yml文件
application:
name: springbootTestApp #应用名称
servlet:
multipart:
enabled: true
max-file-size: 100MB
max-request-size: 100MB
logging:
config: classpath:log4j2.xml
level:
com:
kj:
sbkj:
dao: debug
# mybatis托管mapper文件
mybatis:
mapper-locations: classpath:mapper
@Aspect
@Component
public class OperLogAspect {
final static Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
@Autowired
private LogsMapper logsMapper;//自动注入持久层接口
//格式化日期
public static final String DATE_FORMAT = "yyyy-MM-dd";
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
@Pointcut("@annotation(com.jicr.springboottest.aspectj.OperLog)")
public void operLogPoinCut() {
}
@Before("operLogPoinCut()")
public void logBeforeController(JoinPoint joinPoint) {
logger.info("aop开始打印方法run运行前日志:");
Logs logs = new Logs();
try {
// 从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 获取切入点所在的方法
Method method = signature.getMethod();
// 获取操作
OperLog opLog = method.getAnnotation(OperLog.class);
String serverCode = null;
String serverDesc = null;
if (opLog != null) {
serverCode = opLog.serverCode();
serverDesc = opLog.serverDesc();
}
logger.info("服务码:" + serverCode); // 服务码
logger.info("服务中文描述:" + serverDesc); // 服务中文描述
String reqContent = JsonUtils.objectToJson(joinPoint.getArgs());//请求报文转json格式
String reqContentSub = reqContent.substring(1, reqContent.length() - 1);//去掉两边的[]
JSonObject jsonObject = JsonUtils.jsonTojsonObject(reqContentSub);//json字符串转json对象
logger.info("请求报文:"+jsonObject);
logger.info("请求报文:"+jsonObject);
//getJSonObject()方法:直接获取json对象中的子对象为json对象格式
JSonObject head = jsonObject.getJSonObject("head");
//get()方法:获取json对象中的字段值
String seq=head.get("head_seq_no").toString();
String headReqDate=head.get("head_req_date").toString();
String headReqtime=head.get("head_req_time").toString();
String headReqOrgan=head.get("head_snd_organ").toString();
//给数据库表实体类赋值
logs.setSeq(seq);
logs.setServerCode(serverCode);
logs.setServerName(serverDesc);
logs.setHeadReqDate(dateFormat.parse(headReqDate));
logs.setHeadReqTime(headReqtime);
logs.setHeadReqOrgan(headReqOrgan);
logs.setReqContent(jsonObject.toString());
//插入数据库
logger.info("日志开始插入数据库");
try {
logsMapper.insertOne(logs);
logger.info("日志插入数据库成功");
} catch (Exception e) {
logger.error("日志插入数据库失败:"+e.getMessage());
}
} catch (Exception e) {
logger.error(e.getMessage());
}
}
@AfterReturning(value = "operLogPoinCut()", returning = "returnOb")
public void saveOperLog(JoinPoint joinPoint, Object returnOb) {
logger.info("aop开始打印正常返回通知:");
try {
JSonObject jsonReturn = JsonUtils.jsonTojsonObject(String.valueOf(returnOb));
logger.info("响应报文:"+jsonReturn);
}catch (Exception e){
logger.error(e.getMessage());
}
}
//后置最终通知,final增强,不管是抛出异常或者正常退出都会执行
@After("operLogPoinCut()")
public void after(JoinPoint joinPoint) {
logger.info("aop开始打印后置最终通知");
}
}
八、插入数据库测试
运行项目,用postman发送请求
控制台输出
debug.log文件显示日志
数据库表插入记录
九 、数据库更新
在OperLogAspect.java的@AfterReturning注解中中增加更新语句,用来更新响应报文与响应时间等
OperLogAspect.java文件内容
package com.jicr.springboottest.aspectj;
import com.jicr.springboottest.dao.LogsMapper;
import com.jicr.springboottest.model.table.Logs;
import com.jicr.springboottest.utils.JsonUtils;
import net.sf.json.JSONObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
@Aspect
@Component
public class OperLogAspect {
final static Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
@Autowired
private LogsMapper logsMapper;//自动注入持久层接口
//格式化日期
public static final String DATE_FORMAT = "yyyy-MM-dd";
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
@Pointcut("@annotation(com.jicr.springboottest.aspectj.OperLog)")
public void operLogPoinCut() {
}
@Before("operLogPoinCut()")
public void logBeforeController(JoinPoint joinPoint) {
logger.info("aop开始打印方法run运行前日志:");
Logs logs = new Logs();
try {
// 从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 获取切入点所在的方法
Method method = signature.getMethod();
// 获取操作
OperLog opLog = method.getAnnotation(OperLog.class);
String serverCode = null;
String serverDesc = null;
if (opLog != null) {
serverCode = opLog.serverCode();
serverDesc = opLog.serverDesc();
}
logger.info("服务码:" + serverCode); // 服务码
logger.info("服务中文描述:" + serverDesc); // 服务中文描述
String reqContent = JsonUtils.objectToJson(joinPoint.getArgs());//请求报文转json格式
String reqContentSub = reqContent.substring(1, reqContent.length() - 1);//去掉两边的[]
JSonObject jsonObject = JsonUtils.jsonTojsonObject(reqContentSub);//json字符串转json对象
logger.info("请求报文:"+jsonObject);
logger.info("请求报文:"+jsonObject);
//getJSonObject()方法:直接获取json对象中的子对象为json对象格式
JSonObject head = jsonObject.getJSonObject("head");
//get()方法:获取json对象中的字段值
String seq=head.get("head_seq_no").toString();
String headReqDate=head.get("head_req_date").toString();
String headReqtime=head.get("head_req_time").toString();
String headReqOrgan=head.get("head_snd_organ").toString();
//给数据库表实体类赋值
logs.setSeq(seq);
logs.setServerCode(serverCode);
logs.setServerName(serverDesc);
logs.setHeadReqDate(dateFormat.parse(headReqDate));
logs.setHeadReqTime(headReqtime);
logs.setHeadReqOrgan(headReqOrgan);
logs.setReqContent(jsonObject.toString());
//插入数据库
logger.info("日志开始插入数据库");
try {
logsMapper.insertOne(logs);
logger.info("日志插入数据库成功");
} catch (Exception e) {
logger.error("日志插入数据库失败:"+e.getMessage());
}
} catch (Exception e) {
logger.error(e.getMessage());
}
}
@AfterReturning(value = "operLogPoinCut()", returning = "returnOb")
public void saveOperLog(JoinPoint joinPoint, Object returnOb) {
logger.info("aop开始打印正常返回通知:");
Logs logs = new Logs();
try {
JSonObject jsonReturn = JsonUtils.jsonTojsonObject(String.valueOf(returnOb));
logger.info("响应报文:"+jsonReturn);
JSonObject head = jsonReturn.getJSonObject("head");
String headRspDate = head.get("head_rsp_date").toString();
String headRspTime = head.get("head_rsp_time").toString();
String seq=head.get("head_seq_no").toString();
logs.setSeq(seq);//根据流水号更新
logs.setRspContent(jsonReturn.toString());
logs.setHeadRspDate(dateFormat.parse(headRspDate));
logs.setHeadRspTime(headRspTime);
//更新数据库
logger.info("日志开始更新数据库");
try {
logsMapper.updateOne(logs);
logger.info("日志更新数据库成功");
} catch (Exception e) {
logger.info("日志更新数据库失败");
logger.error(e.getMessage());
}
try {
logsMapper.selectByServerCode(seq);
logger.info("查询数据库成功");
} catch (Exception e) {
logger.info("查询数据库失败");
logger.error(e.getMessage());
}
}catch (Exception e){
logger.error(e.getMessage());
}
}
//后置最终通知,final增强,不管是抛出异常或者正常退出都会执行
@After("operLogPoinCut()")
public void after(JoinPoint joinPoint) {
logger.info("aop开始打印后置最终通知");
}
}
十、数据库更新测试
运行项目,使用postman发送请求
控制台日志
数据库插入并更新日志
十一、数据库查询
查询数据库(日志表一般不用)
控制台日志



