优秀的编程知识分享平台

网站首页 > 技术文章 正文

如何在SpringBoot+MyBatis实现的系统中记录SQL操作?

nanyue 2024-08-18 19:44:51 技术文章 17 ℃

有这样的需求在Spring Boot + MyBatis 实现的系统中记录SQL操作用来进行企业审计操作使用。下面我们就来探讨一下如何实现这个需求。

使用MyBatis的内置日志功能

在MyBatis中提供了内置的日志功能,通过这个内置日志功能来实现SQL操作的记录操作,如下所示。

配置log4j2

要使用log4j2就需要在pom.xml文件中添加相关的依赖配置,如下所示。

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.14.1</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.14.1</version>
</dependency>

接下来就是配置log4j2.xml文件,如下所示。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"/>
        </Console>
        <File name="File" fileName="logs/mybatis.log" append="false">
            <PatternLayout>
                <pattern>%d %p %C{1.} [%t] %m%n</pattern>
            </PatternLayout>
        </File>
    </Appenders>
    <Loggers>
        <Logger name="org.mybatis" level="DEBUG" additivity="false">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="File"/>
        </Logger>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

最后,需要在SpringBoot的配置文件中开启相关的日志配置,如下所示。

logging.config=classpath:log4j2.xml

配置logback

除了使用log4j2,我们还可以通过logback日志框架来进行记录,需要引入相关的依赖配置,如下所示。

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>

配置logback-spring.xml文件

<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/mybatis.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/mybatis-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="org.mybatis" level="DEBUG" additivity="false">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </logger>

    <root level="INFO">
        <appender-ref ref="CONSOLE" />
    </root>
</configuration>

在SpringBoot配置文件中开启logback日志配置,如下所示。

logging.config=classpath:logback-spring.xml

使用MyBatis提供的插件接口

当然我们也可以通过MyBatis提供的插件机制来记录SQL操作,如下所示。

首先,我们先来创建一个插件配置类如下所示。

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import java.sql.Statement;
import java.util.Properties;

@Intercepts({
    @Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class}),
    @Signature(type = StatementHandler.class, method = "update", args = {Statement.class}),
    @Signature(type = StatementHandler.class, method = "batch", args = {Statement.class})
})
public class SqlLogInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        String sql = statementHandler.getBoundSql().getSql();
        System.out.println("Executing SQL: " + sql); // 或者使用日志框架记录
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        // 可以从配置文件中读取一些配置
    }
}

然后需要在MyBatis的配置文件中将这个插件注入到其中,如下所示。

<plugins>
    <plugin interceptor="com.example.demo.SqlLogInterceptor"/>
</plugins>

最后,需要在SpringBoot的配置文件中,引入MyBatis的配置如下所示。

mybatis.config-location=classpath:mybatis-config.xml

使用Spring AOP进行日志记录

除了上面的两种方式之外,我们还可以通过AOP切面操作来实现SQL日志的记录,如下所示。

首先先来定义一个切面操作类,如下所示。

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class SqlLogAspect {

    @Before("execution(* org.apache.ibatis.executor.statement.StatementHandler.*(..))")
    public void logBefore() {
        System.out.println("Before executing SQL"); // 或者使用日志框架记录
    }

    @AfterReturning("execution(* org.apache.ibatis.executor.statement.StatementHandler.*(..))")
    public void logAfter() {
        System.out.println("After executing SQL"); // 或者使用日志框架记录
    }
}

然后需要在SpringBoot的主启动类上通过@EnableAspectJAutoProxy注解来开启日志记录操作。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@SpringBootApplication
@EnableAspectJAutoProxy
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

总结

以上的这些方法都可以帮助我们实现SpringBoot+MyBatis记录SQL查询日志操作,当然具体使用那种方式还是要根据具体的业务需求来进行选择。

Tags:

最近发表
标签列表