公司的项目多数是单数据源,但最近接手了个项目,需要同时操作多个数据库,为此梳理一下Spring Boot多数据源的配置。
一、为什么需要多数据源?
实际开发中,我们经常会遇到这些场景:
- 主业务库 + 日志库分离
- 读写分离(主库写,从库读)
- 跨系统数据同步
Spring Boot原生支持单数据源,但多数据源需要手动配置。
二、配置步骤详解
Step 1:添加Maven依赖
先在pom.xml引入核心依赖,这里用MySQL示例:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> </dependencies>Step 2:配置application.yml
在配置文件中定义两个数据源,比如primary-db(主库)和secondary-db(从库):
spring: datasource: primary: url: jdbc:mysql://localhost:3306/main_db?useSSL=false username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver secondary: url: jdbc:mysql://localhost:3306/log_db?useSSL=false username: log_user password: log@123 driver-class-name: com.mysql.cj.jdbc.DriverStep 3:创建数据源配置类
通过@Configuration定义两个独立的DataSource:
@Configuration public class MultiDataSourceConfig { // 主数据源 @Bean @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } // 从数据源 @Bean @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } }Step 4:指定JPA使用不同数据源
为每个EntityManager指定对应的数据源,避免冲突:
@Configuration @EnableJpaRepositories( basePackages = "com.example.repository.primary", entityManagerFactoryRef = "primaryEntityManager" ) public class PrimaryConfig { @Autowired private DataSource primaryDataSource; @Bean public LocalContainerEntityManagerFactoryBean primaryEntityManager() { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(primaryDataSource); em.setPackagesToScan("com.example.model.primary"); em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); return em; } } // 类似地创建SecondaryConfigStep 5:Service层动态切换数据源
在Service中通过@Qualifier注入对应数据源的操作类:
@Service public class UserService { @Autowired @Qualifier("primaryEntityManager") private EntityManager primaryManager; @Autowired @Qualifier("secondaryEntityManager") private EntityManager secondaryManager; public void saveUser(User user) { primaryManager.persist(user); } public void saveLog(AccessLog log) { secondaryManager.persist(log); } }三、避坑指南
- 事务管理:多数据源需自定义事务管理器,否则事务失效!
- 包路径隔离:主/从库的Entity和Repository必须放在不同包下。
- 连接池优化:生产环境建议用HikariCP,在配置中加
type: com.zaxxer.hikari.HikariDataSource。
四、总结
配置多数据源其实就三步:
- 定义配置→ 2.隔离数据源→ 3.动态注入