概述
本文档专门介绍在Spring Boot环境下如何配置和使用多数据源、MyBatis和Druid连接池的技术组合。本配置支持MySQL和达梦数据库的双数据源架构。
核心技术版本
- Spring Boot: 3.1.4
- MyBatis: 3.0.1 (mybatis-spring-boot-starter)
- Druid: 1.2.18 (druid-spring-boot-starter)
- 数据库驱动: MySQL 8.2.0 + 达梦数据库 8.1.2.141
架构设计原理
Application Layer
├── MySQL DataSource (Primary)
│ ├── Druid Connection Pool
│ ├── MyBatis SqlSessionFactory
│ ├── Transaction Manager
│ └── Mapper Interface (cn.oalo.mapper.mysql.*)
└── DM DataSource (Secondary)
├── Druid Connection Pool
├── MyBatis SqlSessionFactory
├── Transaction Manager
└── Mapper Interface (cn.oalo.mapper.dm.*)
1. Maven依赖配置 (pom.xml)
核心依赖
<dependencies>
<!-- Spring Boot Web Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis Spring Boot Starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.1</version>
</dependency>
<!-- Druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.18</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.2.0</version>
<scope>runtime</scope>
</dependency>
<!-- 达梦数据库驱动 -->
<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmJdbcDriver18</artifactId>
<version>8.1.2.141</version>
</dependency>
</dependencies>
2. 核心配置详解
2.1 Druid多数据源配置 (application.yml)
spring:
# 多数据源配置
datasource:
# MySQL数据源配置
mysql:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test_mysql?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
# 达梦数据库配置
dm:
driver-class-name: dm.jdbc.driver.DmDriver
url: jdbc:dm://localhost:5236
username: SYSDBA
password: Dameng00
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1
test-while-idle: true
test-on-borrow: false
test-on-return: false
# Druid监控配置
druid:
stat-view-servlet:
enabled: true
url-pattern: /druid/*
login-username: admin
login-password: admin
filter:
stat:
enabled: true
log-slow-sql: true
slow-sql-millis: 2000
2.2 Druid连接池参数说明
参数名 | 说明 | 默认值 | 建议值 |
---|---|---|---|
initial-size | 初始化连接数 | 0 | 5-10 |
min-idle | 最小空闲连接数 | 0 | 5-10 |
max-active | 最大活跃连接数 | 8 | 20-50 |
max-wait | 获取连接等待超时时间(ms) | -1 | 60000 |
time-between-eviction-runs-millis | 连接回收间隔时间(ms) | 60000 | 60000 |
min-evictable-idle-time-millis | 最小空闲时间(ms) | 300000 | 300000 |
validation-query | 验证查询语句 | - | SELECT 1 |
test-while-idle | 空闲时检测连接有效性 | false | true |
3. 多数据源配置类详解
3.1 DataSourceConfig.java - 数据源Bean配置
@Configuration
public class DataSourceConfig {
/**
* MySQL数据源配置 - 主数据源
* @Primary注解:多数据源环境下的默认数据源
* @ConfigurationProperties:自动绑定配置文件中的属性
*/
@Bean(name = "mysqlDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.mysql")
public DataSource mysqlDataSource() {
return new DruidDataSource();
}
/**
* 达梦数据库数据源配置 - 辅助数据源
*/
@Bean(name = "dmDataSource")
@ConfigurationProperties(prefix = "spring.datasource.dm")
public DataSource dmDataSource() {
return new DruidDataSource();
}
}
配置要点:
@Primary
- 标记主数据源,Spring在注入DataSource时优先使用@ConfigurationProperties
- 自动绑定yml配置文件中的属性到DruidDataSource- Bean名称要与MyBatis配置中的@Qualifier保持一致
3.2 MybatisConfig.java - MyBatis多数据源配置
3.2.1 MySQL数据源的MyBatis配置
@Configuration
@MapperScan(basePackages = "cn.oalo.mapper.mysql",
sqlSessionTemplateRef = "mysqlSqlSessionTemplate")
static class MysqlMybatisConfig {
/**
* MySQL SqlSessionFactory配置
*/
@Bean(name = "mysqlSqlSessionFactory")
@Primary
public SqlSessionFactory mysqlSqlSessionFactory(@Qualifier("mysqlDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
// 动态设置Mapper XML路径
try {
Resource[] resources = new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/mysql/*.xml");
if (resources.length > 0) {
bean.setMapperLocations(resources);
}
} catch (Exception e) {
System.out.println("MySQL mapper路径不存在,跳过mapper配置");
}
// MyBatis全局配置
Configuration configuration = new Configuration();
configuration.setMapUnderscoreToCamelCase(true); // 驼峰转换
configuration.setLogImpl(StdOutImpl.class); // SQL日志输出
bean.setConfiguration(configuration);
return bean.getObject();
}
/**
* MySQL SqlSessionTemplate配置
*/
@Bean(name = "mysqlSqlSessionTemplate")
@Primary
public SqlSessionTemplate mysqlSqlSessionTemplate(@Qualifier("mysqlSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
/**
* MySQL事务管理器配置
*/
@Bean(name = "mysqlTransactionManager")
@Primary
public DataSourceTransactionManager mysqlTransactionManager(@Qualifier("mysqlDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
3.2.2 达梦数据源的MyBatis配置
@Configuration
@MapperScan(basePackages = "cn.oalo.mapper.dm",
sqlSessionTemplateRef = "dmSqlSessionTemplate")
static class DmMybatisConfig {
@Bean(name = "dmSqlSessionFactory")
public SqlSessionFactory dmSqlSessionFactory(@Qualifier("dmDataSource") DataSource dataSource) throws Exception {
// 配置与MySQL类似,但使用dm数据源
// ...
}
@Bean(name = "dmSqlSessionTemplate")
public SqlSessionTemplate dmSqlSessionTemplate(@Qualifier("dmSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean(name = "dmTransactionManager")
public DataSourceTransactionManager dmTransactionManager(@Qualifier("dmDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
配置要点:
@MapperScan
- 指定不同数据源的Mapper接口扫描路径sqlSessionTemplateRef
- 指定使用的SqlSessionTemplate@Qualifier
- 明确指定注入的Bean- 动态Mapper XML路径检测 - 避免路径不存在时的启动错误
4. Druid监控配置详解
4.1 监控页面配置
spring:
datasource:
druid:
# Web监控配置
stat-view-servlet:
enabled: true # 启用监控页面
url-pattern: /druid/* # 监控页面URL
login-username: admin # 登录用户名
login-password: admin # 登录密码
reset-enable: false # 禁用重置功能
# Web应用配置
web-stat-filter:
enabled: true
url-pattern: /*
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
# Filter配置
filter:
stat:
enabled: true # 启用SQL监控
log-slow-sql: true # 记录慢SQL
slow-sql-millis: 2000 # 慢SQL阈值(ms)
merge-sql: true # 合并相同SQL
wall:
enabled: true # 启用防火墙
config:
multi-statement-allow: true
4.2 监控指标说明
监控项 | 说明 | 关注指标 |
---|---|---|
数据源 | 连接池状态 | 活跃连接数、池中连接数 |
SQL监控 | SQL执行统计 | 执行次数、执行时间、错误次数 |
Web应用 | URL访问统计 | 请求次数、响应时间 |
Session | 会话监控 | 活跃会话数 |
5. 事务管理配置
5.1 声明式事务使用
@Service
@Transactional("mysqlTransactionManager") // 指定MySQL事务管理器
public class UserMysqlService {
@Autowired
private UserMapper userMapper;
public void saveUser(User user) {
userMapper.insert(user);
}
}
@Service
@Transactional("dmTransactionManager") // 指定达梦事务管理器
public class UserDmService {
@Autowired
private UserDmMapper userDmMapper;
public void saveUser(User user) {
userDmMapper.insert(user);
}
}
5.2 分布式事务考虑
对于跨多个数据源的事务,需要考虑:
- 两阶段提交(2PC)
- TCC(Try-Confirm-Cancel)
- 消息队列最终一致性
6. 使用示例
6.1 Mapper接口设计
// MySQL Mapper
package cn.oalo.mapper.mysql;
@Mapper
public interface UserMapper {
@Select("SELECT * FROM users WHERE id = #{id}")
User findById(Long id);
@Insert("INSERT INTO users(name, email) VALUES(#{name}, #{email})")
void insert(User user);
}
// 达梦数据库Mapper
package cn.oalo.mapper.dm;
@Mapper
public interface UserDmMapper {
@Select("SELECT * FROM users WHERE id = #{id}")
User findById(Long id);
@Insert("INSERT INTO users(name, email) VALUES(#{name}, #{email})")
void insert(User user);
}
6.2 服务层使用
@Service
public class UserService {
@Autowired
private UserMapper mysqlUserMapper; // 自动注入MySQL Mapper
@Autowired
private UserDmMapper dmUserMapper; // 自动注入达梦数据库Mapper
public User getUserFromMysql(Long id) {
return mysqlUserMapper.findById(id);
}
public User getUserFromDm(Long id) {
return dmUserMapper.findById(id);
}
}
7. 常见问题与解决方案
7.1 启动问题
问题: 启动时报Mapper路径不存在
org.springframework.core.io.FileNotFoundException: class path resource [mapper/mysql/] cannot be resolved to URL
解决方案: 在SqlSessionFactory配置中添加路径检测
try {
Resource[] resources = new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/mysql/*.xml");
if (resources.length > 0) {
bean.setMapperLocations(resources);
}
} catch (Exception e) {
// 忽略路径不存在的错误
}
7.2 连接问题
问题: 达梦数据库连接失败
Connection refused: connect
解决方案:
- 检查达梦数据库服务是否启动
- 确认端口号(默认5236)
- 检查防火墙设置
- 验证用户名密码
7.3 事务问题
问题: 事务不生效
解决方案:
- 确保类上有
@Service
注解 - 方法必须是public
- 正确指定事务管理器名称
- 避免同一个类内部方法调用
7.4 性能优化
连接池优化建议:
spring:
datasource:
mysql:
druid:
initial-size: 10 # 初始连接数
min-idle: 10 # 最小空闲连接
max-active: 100 # 最大活跃连接
max-wait: 60000 # 获取连接等待时间
validation-query: SELECT 1 FROM DUAL
test-on-borrow: false # 获取时不验证
test-on-return: false # 归还时不验证
test-while-idle: true # 空闲时验证
time-between-eviction-runs-millis: 60000 # 检测间隔
min-evictable-idle-time-millis: 300000 # 最小空闲时间
8. 监控与维护
8.1 关键监控指标
- 连接池使用率 < 80%
- 慢SQL数量 定期清理
- 连接泄露 监控未关闭连接
- 事务执行时间 避免长事务
8.2 日常维护
- 定期查看Druid监控页面
- 分析慢SQL并优化
- 监控数据库连接数
- 备份重要配置文件
配置核心: 多数据源分离 → MyBatis分包扫描 → Druid连接池优化 → 事务管理器隔离
站点网址:https://www.jiafeng.fun
站点头像:https://www.jiafeng.fun/favicon.ico
站点简介(可无):个人博客,前端技术分享