Spring boot 多数据源 + MyBatis + Druid 配置

概述

本文档专门介绍在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初始化连接数05-10
min-idle最小空闲连接数05-10
max-active最大活跃连接数820-50
max-wait获取连接等待超时时间(ms)-160000
time-between-eviction-runs-millis连接回收间隔时间(ms)6000060000
min-evictable-idle-time-millis最小空闲时间(ms)300000300000
validation-query验证查询语句-SELECT 1
test-while-idle空闲时检测连接有效性falsetrue

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();
    }
}

配置要点:

  1. @Primary - 标记主数据源,Spring在注入DataSource时优先使用
  2. @ConfigurationProperties - 自动绑定yml配置文件中的属性到DruidDataSource
  3. 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);
    }
}

配置要点:

  1. @MapperScan - 指定不同数据源的Mapper接口扫描路径
  2. sqlSessionTemplateRef - 指定使用的SqlSessionTemplate
  3. @Qualifier - 明确指定注入的Bean
  4. 动态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

解决方案:

  1. 检查达梦数据库服务是否启动
  2. 确认端口号(默认5236)
  3. 检查防火墙设置
  4. 验证用户名密码

7.3 事务问题

问题: 事务不生效
解决方案:

  1. 确保类上有@Service注解
  2. 方法必须是public
  3. 正确指定事务管理器名称
  4. 避免同一个类内部方法调用

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 日常维护

  1. 定期查看Druid监控页面
  2. 分析慢SQL并优化
  3. 监控数据库连接数
  4. 备份重要配置文件

配置核心: 多数据源分离 → MyBatis分包扫描 → Druid连接池优化 → 事务管理器隔离

打赏
评论区
头像
文章目录

本网站由提供CDN加速/云存储服务