MyBatis 常见日志组件集成详解

MyBatis 常见日志组件集成详解

1. MyBatis 日志系统概述

MyBatis 内置了日志接口,可以自动集成多种流行的日志框架。它会按以下顺序查找日志实现:

  1. SLF4J
  2. Apache Commons Logging
  3. Log4j 2
  4. Log4j
  5. JDK logging

2. 主流日志组件集成

2.1 SLF4J + Logback(推荐)

依赖配置
<!-- Maven 依赖 -->
<dependencies>
    <!-- SLF4J API -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>2.0.6</version>
    </dependency>
    
    <!-- Logback 实现 -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.4.5</version>
    </dependency>
    
    <!-- MyBatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.11</version>
    </dependency>
</dependencies>
Logback 配置文件
<!-- src/main/resources/logback.xml -->
<configuration>
    <!-- 控制台输出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- MyBatis SQL 日志配置 -->
    <logger name="com.example.mapper" level="DEBUG" />
    
    <!-- 显示执行的SQL语句和参数 -->
    <logger name="java.sql.Connection" level="DEBUG"/>
    <logger name="java.sql.Statement" level="DEBUG"/>
    <logger name="java.sql.PreparedStatement" level="DEBUG"/>
    <logger name="java.sql.ResultSet" level="DEBUG"/>
    
    <!-- MyBatis 日志 -->
    <logger name="org.apache.ibatis" level="INFO"/>
    
    <!-- 根日志级别 -->
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
    </root>
</configuration>

2.2 Log4j2

依赖配置
<!-- Maven 依赖 -->
<dependencies>
    <!-- Log4j2 -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.19.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.19.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.19.0</version>
    </dependency>
</dependencies>
Log4j2 配置文件
<!-- src/main/resources/log4j2.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        
        <!-- 文件输出 -->
        <File name="MyFile" fileName="logs/mybatis.log">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </File>
    </Appenders>
    
    <Loggers>
        <!-- MyBatis Mapper 接口的SQL日志 -->
        <Logger name="com.example.mapper" level="DEBUG" additivity="false">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="MyFile"/>
        </Logger>
        
        <!-- SQL 执行日志 -->
        <Logger name="java.sql" level="DEBUG"/>
        <Logger name="org.apache.ibatis" level="INFO"/>
        
        <Root level="INFO">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

2.3 Log4j

依赖配置
<!-- Maven 依赖 -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
Log4j 配置文件
# src/main/resources/log4j.properties
# 根日志级别
log4j.rootLogger=INFO, stdout

# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

# MyBatis SQL 日志
log4j.logger.com.example.mapper=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG

2.4 标准输出(StdOut)日志

在 MyBatis 配置中启用
<!-- mybatis-config.xml -->
<configuration>
    <settings>
        <!-- 使用标准输出日志 -->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
</configuration>

3. Spring Boot 中的日志配置

3.1 Spring Boot + Logback(默认)

# application.properties
# MyBatis Mapper 日志级别
logging.level.com.example.mapper=DEBUG

# SQL 相关日志
logging.level.java.sql.Connection=DEBUG
logging.level.java.sql.Statement=DEBUG
logging.level.java.sql.PreparedStatement=DEBUG

# MyBatis 框架日志
logging.level.org.mybatis=INFO
logging.level.org.apache.ibatis=INFO

# 日志文件输出
logging.file.name=logs/myapp.log
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %msg%n
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n

3.2 Spring Boot + Log4j2

<!-- pom.xml 中排除默认日志,引入 Log4j2 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
# application.yml
logging:
  level:
    com.example.mapper: DEBUG
    java.sql: DEBUG
  config: classpath:log4j2.xml

4. 日志输出效果示例

4.1 SQL 执行日志示例

2023-10-01 14:30:25.123 [http-nio-8080-exec-1] DEBUG c.e.m.UserMapper.selectById - ==>  Preparing: SELECT * FROM users WHERE id = ? 
2023-10-01 14:30:25.124 [http-nio-8080-exec-1] DEBUG c.e.m.UserMapper.selectById - ==> Parameters: 1(Long)
2023-10-01 14:30:25.126 [http-nio-8080-exec-1] DEBUG c.e.m.UserMapper.selectById - <==      Total: 1

4.2 详细 SQL 日志配置

<!-- 更详细的 SQL 日志配置 -->
<logger name="com.example.mapper" level="TRACE"/>
<logger name="java.sql" level="TRACE"/>

5. 高级日志配置技巧

5.1 按环境配置不同的日志级别

<!-- logback-spring.xml -->
<springProfile name="dev">
    <logger name="com.example.mapper" level="DEBUG"/>
    <logger name="java.sql" level="DEBUG"/>
</springProfile>

<springProfile name="prod">
    <logger name="com.example.mapper" level="WARN"/>
    <logger name="java.sql" level="WARN"/>
</springProfile>

5.2 SQL 执行时间监控

// 自定义拦截器监控 SQL 执行时间
@Intercepts({@Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class})})
public class SqlExecuteTimeInterceptor implements Interceptor {
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        long startTime = System.currentTimeMillis();
        try {
            return invocation.proceed();
        } finally {
            long endTime = System.currentTimeMillis();
            long executeTime = endTime - startTime;
            
            // 记录执行时间过长的 SQL
            if (executeTime > 1000) {
                Logger logger = LoggerFactory.getLogger("SLOW_SQL");
                logger.warn("Slow SQL detected, execution time: {}ms", executeTime);
            }
        }
    }
}

6. 常见问题与解决方案

6.1 日志冲突问题

<!-- 解决日志框架冲突 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

6.2 日志不输出问题排查

// 检查日志配置
public class LogConfigChecker {
    public static void main(String[] args) {
        // 检查所有日志框架
        LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
        StatusPrinter.print(lc);
        
        // 测试日志输出
        Logger logger = LoggerFactory.getLogger(LogConfigChecker.class);
        logger.debug("Debug message");
        logger.info("Info message");
    }
}

6.3 生产环境日志配置

<!-- 生产环境日志配置 -->
<configuration>
    <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>
            <maxHistory>30</maxHistory>
            <totalSizeCap>3GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 生产环境只记录 WARN 级别以上的日志 -->
    <root level="WARN">
        <appender-ref ref="FILE"/>
    </root>
    
    <!-- 但 MyBatis SQL 日志仍然记录 DEBUG -->
    <logger name="com.example.mapper" level="DEBUG"/>
</configuration>

7. 最佳实践总结

  1. 开发环境:使用 SLF4J + Logback,开启 DEBUG 级别 SQL 日志
  2. 生产环境:关闭 DEBUG 日志,使用文件输出,定期归档
  3. 日志级别
    • Mapper 接口:DEBUG(查看 SQL)
    • java.sql 包:DEBUG(查看参数和结果)
    • org.apache.ibatis:INFO 或 WARN
  4. 性能考虑:生产环境避免输出过多 DEBUG 日志
  5. 安全考虑:确保日志中不记录敏感信息(如密码)

通过合理配置日志组件,可以有效地监控 MyBatis 的 SQL 执行情况,便于调试和性能优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

步行cgn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值