-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
Description
我在使用多数据源的情况下,尝试整合MyBatis-plus的多数据源的情况下出现了点问题,是这样的,我们项目中除了使用apijson外,也需要自己进行写一些增删改的接口,而且也要支持多数据源,所以这里我尝试整合MyBatis-plus的多数据源,我初步是整合成功了,通过apijson和自己写的接口,都可进行多数据源的增删改查,但是出现了一些问题,当项目使用一段时间,控制台就会报错:Too many connections(MySQL 错误码 1040)就是数据库连接太多了,比如我通过一直调用apijson的get方法,调用一两百次,就会复现这个问题,我怀疑是没有正常关闭连接的问题,但是我始终找不到问题点在哪里,为了实现两者整合,我重写了DemoSQLExecutor的getConnection方法,以可以从MyBatis-plus的多数据源地方获取DataSource,然后取消了原本的通过DemoDataSourceConfig的@bean方式注入DruidDataSource的代码,然后修改了一下配置,改动如下
请问Tommy哥,这种情况有办法解决吗?
环境:Java21+SpringBoot3.2.5+MySQL8.0.24+dynamic-datasource4.3.1(MyBatis-plus的多数据源包)
重写的DemoSQLExecutor的getConnection方法
@OverRide
public Connection getConnection(SQLConfig config) throws Exception {
String key = config.getDatasource() + "-" + config.getDatabase();
Connection c = connectionMap.get(key);
if (c == null || c.isClosed()) {
// 获取 Spring 上下文和 Environment
ApplicationContext ctx = DemoApplication.getApplicationContext();
if (ctx == null) {
throw new IllegalStateException("无法获取 Spring ApplicationContext");
}
Environment env = ctx.getEnvironment();
// 3) 获取要使用的 dataSource 名(前端通过@datasource来指定)
String requested = config.getDatasource();
DataSource ds = null;
Map<String, DataSource> provided = new HashMap<>();
// 如果容器有 DynamicDataSourceProvider bean(starter 情况),直接取出 provider 管理的 map
if (ctx.getBeanNamesForType(DynamicDataSourceProvider.class).length > 0) {
DynamicDataSourceProvider provider = ctx.getBean(DynamicDataSourceProvider.class);
provided = provider.loadDataSources();
ds = provided.get(requested);
}
// 4) 如果没找到,尝试从配置读取默认数据源名(spring.datasource.dynamic.primary)
if (ds == null) {
String primaryName = null;
try {
primaryName = env.getProperty("spring.datasource.dynamic.primary");
} catch (Throwable ignored) {}
if (primaryName != null && !primaryName.isBlank()) {
ds = provided.get(primaryName);
}
}
// 5) 最后兜底:如果 ds 仍然为空且 dsMap 只有一个元素,则取唯一那个
if (ds == null && provided.size() == 1) {
ds = provided.values().iterator().next();
}
// 7) 获取连接并缓存(保留原先的 connectionMap 逻辑)
connectionMap.put(key, ds == null ? null : ds.getConnection());
}
// 保持原来的逻辑:必须最后执行 super.getConnection(config)
return super.getConnection(config);
}
配置:
spring:
datasource:
dynamic:
primary: druid # 指定默认数据源名称
datasource:
druid:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/office_automation?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
druid-test:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://14.70.22.777:33336/office_automation?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
username: ENC(fXGOMv7Vggup2KAbAyHoI6Mzd7lqblJdxi1CSt8CZvAjGHen5rAj6HiwKt5W)
password: ENC(n24kDLyLtsv2HJCpwhKzIJycd/UD+NYy88c2haiS7mIUj0S/2Am8sQ==)
type: com.alibaba.druid.pool.DruidDataSource
MyBatis-plus的多数据源依赖包的坐标:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
<version>4.3.1</version>
</dependency>
DemoDataSourceConfig类中的代码全部注释掉了
报错信息:
