# multiply-ds **Repository Path**: zoyation/spring-boot-multiply-ds ## Basic Information - **Project Name**: multiply-ds - **Description**: SpringBoot实现多数据源动态切换功能,功能具备以下特点: 1、双重数据源初始化方式:支持通过配置文件和数据库配置表两种方式初始化数据源。 2、多样化数据源切换策略:提供基于AOP注解、用户身份和数据源名称三种切换方式。 3、统一事务管控机制:采用DynamicDataSource统一管理数据源,结合@Transactional实现事务控制。 - **Primary Language**: Java - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-06-19 - **Last Updated**: 2025-11-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SpringBoot多数据源 ## 功能介绍 本文介绍如何使用SpringBoot实现多数据源动态切换功能。该方案具备以下特点: * **双重数据源初始化方式**:支持通过配置文件和数据库配置表两种方式初始化数据源。 * **多样化数据源切换策略**:提供基于AOP注解、用户身份和数据源名称三种切换方式。 * **统一事务管控机制**:采用DynamicDataSource统一管理数据源,结合@Transactional(rollbackFor = Exception.class)实现事务控制。 * **跨数据源事务**:如果需要配置的多个数据库都支持JTA,可以配置JTA实现跨数据源事务,通过两阶段提交协议保证所有参与的资源要么全部提交,要么全部回滚。 * **简化配置与部署**:相较于网络上常见实现方案,本方案配置更简洁,代码量更少。 通过以下方式集成JTA: 1. 添加JTA依赖(如Atomikos或Bitronix) 2. 配置JTA事务管理器 3. 将多个数据源配置为XA数据源 4. 使用@Transactional注解管理事务边界 ## 主要功能 ### (1)初始化数据源 数据源初始化方式有两种: 1. 通过配置文件初始化多数据源配置 application.yml中“spring.dynamic-datasource.from” 值为CONFIG时,通过“datasoucre-list”初始化数据源,配置示例如下: ```yaml spring: dynamic-datasource: #DB-数据库,CONF-配置文件 from: CONF #获取数据源的sql #datasource-sql: select id as name,driver-class-name,url,username,password from t_datasource datasource-list: - name: h2-1 driver-class-name: org.h2.Driver url: jdbc:h2:mem:test username: h2 password: h2 - name: derby-1 driver-class-name: org.apache.derby.jdbc.EmbeddedDriver url: jdbc:derby:derbyDb;create=true username: derby password: derby ``` 2. 通过数据库表初始化多数据源 application.yml中“spring.dynamic-datasource.from” 值为DB时,通过“datasource-sql”参数设置的主库里数据源查询SQL语句初始化数据源,配置示例如下: ```yaml spring: dynamic-datasource: #DB-数据库,CONF-配置文件 from: CONF #获取数据源的sql datasource-sql: select id as name,driver-class-name,url,username,password from t_datasource ``` ### (2)切换数据源 1. 通过AOP+注解切换数据源 2. 按访问用户切换数据源 3. 按数据源名称切换数据源 ### (3)事务控制 该示例只需初始化一个数据源"DynamicDataSource"。 如果当前线程没设置数据源名称,使用默认数据源(比如系统管理主数据库、公共配置信息数据库),如果当前线程设置了数据源名称,会按数据源名称获取数据库连接,用Spring事务注解"@Transactional(rollbackFor = Exception.class)"统一控制事务。 ## 访问测试 添加测试Controller“DynamicDatasourceController”进行测试。 1. 查询默认数据源: http://localhost:8080/test/base/getAllDatasource 2. 查询其他数据源: http://localhost:8080/test/base/getByDatasourceName?name=h2-1 http://localhost:8080/test/base/getByDatasourceName?name=derby-1 3. 按注解切换查询: http://localhost:8080/test/base/getByAnnotationH2 http://localhost:8080/test/base/getByAnnotationDerby 4. 多数据源事务测试 http://localhost:8080/test/base/testTransaction ## 总结 本方案实现了完整的SpringBoot多数据源动态切换功能,具有以下核心特性: ### 核心组件架构 1. **数据源管理核心**: [DynamicDataSource](file://D:\IdeaProjects\spring-boot-multiply-ds\src\main\java\com\tony\jdbc\dynamic\datasource\DynamicDataSource.java#L27-L205) 类继承 `HikariDataSource` 并实现 `InitializingBean` 接口,负责管理多个数据源实例和动态切换逻辑。 2. **数据源持有者**: [DynamicDataSourceKeyHolder](file://D:\IdeaProjects\spring-boot-multiply-ds\src\main\java\com\tony\jdbc\dynamic\datasource\DynamicDataSourceKeyHolder.java#L7-L45) 通过ThreadLocal维护当前线程的数据源标识。 3. **配置管理**: [DynamicDataSourceProperties](file://D:\IdeaProjects\spring-boot-multiply-ds\src\main\java\com\tony\jdbc\dynamic\config\DynamicDataSourceProperties.java#L15-L31) 用于读取和管理数据源配置信息。 ### 三大数据源初始化方式 - **配置文件方式**: 通过application.yml中的 `datasource-list` 配置静态数据源 - **数据库方式**: 通过SQL查询动态获取数据源配置信息 - **运行时管理**: 支持动态添加、更新和删除数据源实例 ### 三种数据源切换策略 1. **AOP注解方式** - 使用 [@DynamicDatasource](file://D:\IdeaProjects\spring-boot-multiply-ds\src\main\java\com\tony\jdbc\dynamic\annotation\DynamicDatasource.java#L12-L19) 注解标记需要切换数据源的方法或类 - 通过 [DynamicDatasourceAspect](file://D:\IdeaProjects\spring-boot-multiply-ds\src\main\java\com\tony\jdbc\dynamic\aspect\DynamicDatasourceAspect.java#L22-L59) 切面在方法执行前后自动切换数据源 2. **Web拦截器方式** - 通过 [DynamicDatasourceInterceptor](file://D:\IdeaProjects\spring-boot-multiply-ds\src\main\java\com\tony\jdbc\dynamic\interceptor\DynamicDatasourceInterceptor.java#L16-L60) 拦截Controller请求 - 可基于用户身份等请求信息动态切换数据源 3. **编程式切换方式** - 通过 [IDynamicService](file://D:\IdeaProjects\spring-boot-multiply-ds\src\main\java\com\tony\jdbc\dynamic\service\IDynamicService.java#L13-L65) 接口封装数据源切换逻辑 - 内置事务管理,确保数据一致性 ### 统一事务控制 - 结合Spring的 `@Transactional(rollbackFor = Exception.class)` 实现统一事务管理 - 默认数据源与动态数据源无缝集成 - 通过 [ITransactionService](file://D:\IdeaProjects\spring-boot-multiply-ds\src\main\java\com\tony\jdbc\dynamic\service\ITransactionService.java#L9-L25) 提供事务执行能力 ### 方案优势 - 配置简单,易于集成 - 代码量少,逻辑清晰 - 支持多种切换策略,适应不同业务场景 - 具备良好的扩展性和维护性 - 提供完整的测试用例和API接口 该方案能够有效解决企业级应用中多数据源管理的复杂性问题,提升开发效率和系统稳定性。