SpringBoot + Mybatis 多数据源配置打印SQL失效问题(mybatis.configuration.log-impl)

本文介绍了如何在Spring Boot应用中通过自定义MybatisLogCustom类实现SQL日志的打印,包括单数据源配置和多数据源环境下如何配置。重点讲解了如何在多数据源配置中仅在特定数据源上启用SQL日志记录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、单数据源

一个数据源时直接在 application.yaml 文件中增加如下配置即可实现sql日志的打印

mybatis:
    configuration:
        map-underscore-to-camel-case: true
        log-impl: com.ylx.apis_plugin_supervise.config.mybatis.log.MybatisLogCustom

MybatisLogCustom 类为自定义的SQL打印配置类

import org.apache.ibatis.logging.Log;

public class MybatisLogCustom implements Log {

    public MybatisLogCustom(String clazz) {
    }

    @Override
    public boolean isDebugEnabled() {
        return true;
    }
    @Override
    public boolean isTraceEnabled() {
        return true;
    }
    @Override
    public void error(String s, Throwable e) {
        System.err.println(s);
        e.printStackTrace(System.err);
    }
    @Override
    public void error(String s) {
        System.out.println("mybatis error");
        System.err.println(s);
    }
    @Override
    public void debug(String s) {
        // System.out.println("mybatis debug");

        // 放开注释,打印 mybatis执行sql
        System.out.println(s);
    }
    @Override
    public void trace(String s) {
        // System.out.println("mybatis trace");

        // 放开注释,打印 mybatis执行sql的返回结果
        // System.out.println(s);
    }
    @Override
    public void warn(String s) {
        System.out.println("mybatis warn");
        System.out.println(s);
    }
}

二、mybatis配置多个数据源

只需要在多数据源中的一个配置类中增加如下配置即可

// 多数据源配置类中增加 Configuration
@Bean
@ConfigurationProperties(prefix = "mybatis.configuration")
public org.apache.ibatis.session.Configuration globalConfiguration() {
    return new org.apache.ibatis.session.Configuration();
}

// 在其中一个数据源中增加如下代码即可,不需要在所有数据源配置中都增加
sessionFactoryBean.setConfiguration(configuration);

具体参考:

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = "com.ylx.apis_plugin_supervise.mybatis.ubkplugin.dao",sqlSessionFactoryRef = "ubkpluginSqlSessionFactory")
public class UbkPluginDataSourceConfig {
    @Bean
    @ConfigurationProperties(prefix = "mybatis.configuration")
    public org.apache.ibatis.session.Configuration globalConfiguration() {
        return new org.apache.ibatis.session.Configuration();
    }

    @Primary
    @Bean(name = "ubkpluginDataSource")
    @ConfigurationProperties("spring.datasource.ubkplugin")
    public DataSource masterDataSource(){
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "ubkpluginSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("ubkpluginDataSource") DataSource dataSource,
                                               org.apache.ibatis.session.Configuration configuration) throws Exception {
        SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
        sessionFactoryBean.setDataSource(dataSource);

        sessionFactoryBean.setConfiguration(configuration);

        sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath:mapper/ubkplugin/*.xml"));
        return sessionFactoryBean.getObject();
    }
}
### Java SQL连接异常问题解决方案 #### 错误分析 `java.sql.SQLTransientConnectionException: Get Location Cache Fail conn=2890275` 是一种常见的数据库连接异常,通常发生在 OceanBase 数据库环境中。该错误表明客户端无法成功获取分区的位置信息(Location Cache),这可能是由于配置不当、网络问题或驱动版本不兼容引起的。 --- #### 配置文件调整 在 `application-dev.yml` 文件中,可能存在一些配置项未正确设置的情况。以下是可能的改进方向: 1. **确认 MySQL 驱动版本** 使用的 MySQL 驱动版本应遵循官方推荐,不得超过 8.0.25 版本[^3]。如果当前使用的驱动版本过高,则可能导致兼容性问题。 2. **数据源 URL 参数优化** 确保 `url` 中的时间区参数和字符编码参数正确无误。例如: ```yaml url: jdbc:mysql://localhost:3306/guigu-oa?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8 ``` 如果时间区或字符集配置有误,可能会间接影响位置缓存的获取过程[^1]。 3. **MyBatis 日志调试** 启用 MyBatis日志功能可以帮助定位问题所在。通过查看详细的执行日志,可以进一步判断是否存在其他潜在问题: ```yaml mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl ``` --- #### 缓存刷新机制排查 根据 OceanBase 内核研发工程师的相关说明[^4],`location cache` 的刷新机制是一个重要环节。当发生 `Get Location Cache Fail` 错误时,可以从以下几个方面入手: 1. **单独刷新缓存** 尝试手动触发 `__all_core_table` 或 `__all_root_table` 的 `location_cache` 刷新操作[^2]。可以通过以下方式实现: - 执行特定的 SQL 查询来强制更新缓存。 - 检查是否有长时间未刷新的分区元信息。 2. **检查副本分布状态** 分布式集群中的副本位置信息管理至关重要。如果某些节点的状态不稳定,也可能导致缓存失效。需确保所有副本均处于正常工作状态。 --- #### 连接池配置优化 HikariCP 是常用的数据库连接池工具,在其配置过程中需要注意以下几点: 1. **最大连接数限制** 设置合理的最大连接数 (`maximumPoolSize`) 和最小空闲连接数 (`minimumIdle`) 可以有效减少因资源不足引发的连接失败风险。 ```yaml spring: datasource: hikari: maximum-pool-size: 20 minimum-idle: 5 ``` 2. **超时时间调整** 增加连接超时时间和读取超时时间有助于应对高延迟场景下的请求失败情况: ```yaml connection-timeout: 30000 # 30秒 socket-timeout: 60000 # 60秒 ``` --- #### 示例代码 以下是一段基于 Spring Boot 的数据库连接测试代码,可用于验证上述修改后的效果: ```java import javax.sql.DataSource; import java.sql.Connection; public class DatabaseTest { public static void main(String[] args) throws Exception { DataSource dataSource = ApplicationContextHolder.getBean(DataSource.class); try (Connection connection = dataSource.getConnection()) { System.out.println("Database Connection Successful!"); } catch (Exception e) { System.err.println("Error occurred while connecting to the database:"); e.printStackTrace(); } } } ``` --- ### 总结 综合以上分析,解决 `java.sql.SQLTransientConnectionException: Get Location Cache Fail` 问题的关键在于: 1. 确认并调整 MySQL 驱动版本至合适范围; 2. 完善 `application-dev.yml` 配置文件的内容; 3. 排查分布式环境中的副本状态以及缓存刷新逻辑; 4. 对 HikariCP 进行必要的性能调优。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值