java全家桶之25: Spring Boot 中配置 Druid 多数据源
在 Spring Boot 应用中配置多个 Druid 数据源是常见的需求,特别是在需要连接多个数据库的场景下。以下是完整的配置方法和最佳实践。
·
在 Spring Boot 应用中配置多个 Druid 数据源是常见的需求,特别是在需要连接多个数据库的场景下。以下是完整的配置方法和最佳实践。
一、基础配置步骤
1. 添加依赖
首先确保 pom.xml 中包含必要的依赖:
xml
复制
下载
运行
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.8</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
2. 配置 application.yml
yaml
复制
下载
spring: datasource: # 主数据源 primary: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/primary_db username: root password: 123456 druid: initial-size: 5 max-active: 20 min-idle: 5 max-wait: 60000 # 从数据源 secondary: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/secondary_db username: root password: 123456 druid: initial-size: 3 max-active: 15 min-idle: 3 max-wait: 30000
二、Java 配置类实现
1. 主数据源配置
java
复制
下载
@Configuration public class DataSourceConfig { @Primary @Bean(name = "primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource primaryDataSource() { return DruidDataSourceBuilder.create().build(); } @Bean(name = "secondaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSource secondaryDataSource() { return DruidDataSourceBuilder.create().build(); } }
2. 配置事务管理器
java
复制
下载
@Configuration @EnableTransactionManagement public class TransactionConfig { @Bean @Primary public PlatformTransactionManager primaryTransactionManager( @Qualifier("primaryDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean public PlatformTransactionManager secondaryTransactionManager( @Qualifier("secondaryDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } }
三、MyBatis 多数据源配置
1. 主数据源 MyBatis 配置
java
复制
下载
@Configuration @MapperScan(basePackages = "com.example.mapper.primary", sqlSessionFactoryRef = "primarySqlSessionFactory") public class PrimaryMyBatisConfig { @Primary @Bean(name = "primarySqlSessionFactory") public SqlSessionFactory primarySqlSessionFactory( @Qualifier("primaryDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations( new PathMatchingResourcePatternResolver() .getResources("classpath:mapper/primary/*.xml")); return bean.getObject(); } @Primary @Bean(name = "primarySqlSessionTemplate") public SqlSessionTemplate primarySqlSessionTemplate( @Qualifier("primarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); } }
2. 从数据源 MyBatis 配置
java
复制
下载
@Configuration @MapperScan(basePackages = "com.example.mapper.secondary", sqlSessionFactoryRef = "secondarySqlSessionFactory") public class SecondaryMyBatisConfig { @Bean(name = "secondarySqlSessionFactory") public SqlSessionFactory secondarySqlSessionFactory( @Qualifier("secondaryDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations( new PathMatchingResourcePatternResolver() .getResources("classpath:mapper/secondary/*.xml")); return bean.getObject(); } @Bean(name = "secondarySqlSessionTemplate") public SqlSessionTemplate secondarySqlSessionTemplate( @Qualifier("secondarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); } }
四、JPA/Hibernate 多数据源配置
1. 主数据源 JPA 配置
java
复制
下载
@Configuration @EnableJpaRepositories( basePackages = "com.example.repository.primary", entityManagerFactoryRef = "primaryEntityManagerFactory", transactionManagerRef = "primaryTransactionManager") public class PrimaryJpaConfig { @Primary @Bean(name = "primaryEntityManagerFactory") public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory( EntityManagerFactoryBuilder builder, @Qualifier("primaryDataSource") DataSource dataSource) { return builder .dataSource(dataSource) .packages("com.example.entity.primary") .persistenceUnit("primary") .properties(jpaProperties()) .build(); } private Map<String, Object> jpaProperties() { Map<String, Object> props = new HashMap<>(); props.put("hibernate.dialect", "org.hibernate.dialect.MySQL8Dialect"); props.put("hibernate.hbm2ddl.auto", "update"); return props; } }
2. 从数据源 JPA 配置
java
复制
下载
@Configuration @EnableJpaRepositories( basePackages = "com.example.repository.secondary", entityManagerFactoryRef = "secondaryEntityManagerFactory", transactionManagerRef = "secondaryTransactionManager") public class SecondaryJpaConfig { @Bean(name = "secondaryEntityManagerFactory") public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory( EntityManagerFactoryBuilder builder, @Qualifier("secondaryDataSource") DataSource dataSource) { return builder .dataSource(dataSource) .packages("com.example.entity.secondary") .persistenceUnit("secondary") .properties(jpaProperties()) .build(); } private Map<String, Object> jpaProperties() { Map<String, Object> props = new HashMap<>(); props.put("hibernate.dialect", "org.hibernate.dialect.MySQL8Dialect"); props.put("hibernate.hbm2ddl.auto", "update"); return props; } }
五、动态数据源配置(高级)
对于需要运行时动态切换数据源的场景:
1. 创建动态数据源类
java
复制
下载
public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSourceType(); } }
2. 数据源上下文持有类
java
复制
下载
public class DataSourceContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); public static void setDataSourceType(String dataSourceType) { contextHolder.set(dataSourceType); } public static String getDataSourceType() { return contextHolder.get(); } public static void clearDataSourceType() { contextHolder.remove(); } }
3. 配置动态数据源
java
复制
下载
@Configuration public class DynamicDataSourceConfig { @Bean @Primary public DataSource dynamicDataSource( @Qualifier("primaryDataSource") DataSource primaryDataSource, @Qualifier("secondaryDataSource") DataSource secondaryDataSource) { Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put("primary", primaryDataSource); targetDataSources.put("secondary", secondaryDataSource); DynamicDataSource dynamicDataSource = new DynamicDataSource(); dynamicDataSource.setTargetDataSources(targetDataSources); dynamicDataSource.setDefaultTargetDataSource(primaryDataSource); return dynamicDataSource; } }
六、监控配置
为每个数据源配置独立的监控:
java
复制
下载
@Configuration public class DruidMonitorConfig { @Bean public ServletRegistrationBean<StatViewServlet> primaryStatViewServlet() { ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/primary/*"); bean.addInitParameter("loginUsername", "admin"); bean.addInitParameter("loginPassword", "123456"); return bean; } @Bean public ServletRegistrationBean<StatViewServlet> secondaryStatViewServlet() { ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/secondary/*"); bean.addInitParameter("loginUsername", "admin"); bean.addInitParameter("loginPassword", "123456"); return bean; } }
七、最佳实践建议
-
命名规范:
-
为每个数据源使用清晰的命名(如 primary/secondary)
-
包结构按数据源分离(mapper.primary, mapper.secondary)
-
-
事务管理:
-
避免跨数据源事务
-
如需分布式事务考虑使用Seata等框架
-
-
性能优化:
-
根据业务负载调整各数据源的连接池参数
-
监控各数据源的使用情况
-
-
安全考虑:
-
为监控页面设置强密码
-
生产环境禁用DDL自动更新(hibernate.hbm2ddl.auto)
-
通过以上配置,可以在Spring Boot应用中灵活使用多个Druid数据源,并根据业务需求选择最适合的配置方式。

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)