# abstract-routing-datasource-demo **Repository Path**: tree_boss/abstract-routing-datasource-demo ## Basic Information - **Project Name**: abstract-routing-datasource-demo - **Description**: 多数据源,读写分离 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-30 - **Last Updated**: 2025-10-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AbstractRoutingDataSource 动态数据源路由示例 ## 项目介绍 本项目演示了如何在Spring Boot应用中使用Spring的`AbstractRoutingDataSource`实现动态数据源路由和读写分离功能。该技术广泛应用于需要多数据源、读写分离的企业级应用场景,可以有效提高系统的并发性能和可扩展性。 ## 技术栈 - Spring Boot 2.7.18 - MyBatis-Plus 3.4.3.4 - Druid 连接池 1.1.18 - MySQL 8.0.32 - Spring AOP ## 功能特点 1. **动态数据源路由**:基于`AbstractRoutingDataSource`实现数据源动态切换 2. **读写分离**:支持自动识别SQL操作类型(读/写)并路由到对应数据源 3. **注解方式**:通过自定义`@DataSource`注解灵活指定数据源 4. **ThreadLocal实现**:使用`ThreadLocal`保证线程安全的数据源选择 ## 快速开始 ### 环境要求 - JDK 1.8+ - Maven 3.6+ - MySQL 5.7+ ### 安装与运行 1. 克隆项目 ```bash git clone [repository-url] cd abstract-routing-datasource-demo ``` 2. 修改数据库配置 编辑`src/main/resources/application.yml`文件,修改数据库连接信息: ```yaml spring: datasource: # 主库配置 master: url: jdbc:mysql://localhost:3306/master_db?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: 123456 # ... # 从库配置 slave: url: jdbc:mysql://localhost:3306/slave_db?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: 123456 # ... ``` 3. 编译运行 ```bash mvn clean install mvn spring-boot:run ``` ## 项目结构 ``` src/main/java/com/example/ ├── AbstractRoutingDataSourceDemo.java # 应用启动类 ├── annotation/ # 自定义注解 │ └── DataSource.java # 数据源选择注解 ├── aspect/ # AOP切面 │ ├── DataSourceAspect.java # 注解方式数据源切换切面 │ └── ReadWriteSplitAspect.java # 自动读写分离切面 ├── config/ # 配置类 │ └── DataSourceConfig.java # 数据源配置 ├── dataSource/ # 数据源相关 │ ├── DynamicDataSource.java # 动态数据源实现 │ └── MyBatisPlusConfig.java # MyBatis-Plus配置 ├── entity/ # 实体类 │ └── User.java # 用户实体 ├── enums/ # 枚举类 │ └── DataSourceType.java # 数据源类型枚举 ├── mapper/ # Mapper接口 │ └── UserMapper.java # 用户Mapper ├── service/ # 服务层 │ ├── UserService.java # 用户服务接口 │ └── impl/ │ └── UserServiceImpl.java # 用户服务实现 └── utils/ # 工具类 └── DataSourceContextHolder.java # 数据源上下文持有器 ``` ## 核心实现原理 ### 1. 数据源类型枚举 定义了主库和从库两种数据源类型: ```java public enum DataSourceType { MASTER, SLAVE } ``` ### 2. 数据源上下文持有器 使用ThreadLocal存储当前线程使用的数据源类型: ```java public class DataSourceContextHolder { private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>(); // 设置数据源类型 public static void setDataSourceType(DataSourceType dataSourceType) { ... } // 获取数据源类型 public static DataSourceType getDataSourceType() { ... } // 清除数据源类型 public static void clearDataSourceType() { ... } } ``` ### 3. 动态数据源实现 继承AbstractRoutingDataSource并重写determineCurrentLookupKey方法: ```java public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSourceType(); } } ``` ### 4. 数据源配置 配置多个数据源并设置到动态数据源中: ```java @Configuration public class DataSourceConfig { @Bean @ConfigurationProperties(prefix = "spring.datasource.master") public DataSource masterDataSource() { ... } @Bean @ConfigurationProperties(prefix = "spring.datasource.slave") public DataSource slaveDataSource() { ... } @Bean @Primary public DataSource dynamicDataSource(DataSource masterDataSource, DataSource slaveDataSource) { // 设置数据源映射和默认数据源 ... } } ``` ### 5. 数据源切换切面 通过AOP实现数据源的动态切换: - 注解方式:通过@DataSource注解指定数据源 - 自动方式:通过方法名前缀识别读写操作并自动切换数据源 ## 使用方式 ### 1. 注解方式 在Service方法上添加@DataSource注解指定数据源: ```java @Service public class UserServiceImpl implements UserService { // 默认使用主库(写操作) @Override public boolean saveUser(User user) { ... } // 手动指定使用从库(读操作) @DataSource(DataSourceType.SLAVE) @Override public User getUserById(Integer id) { ... } } ``` ### 2. 自动方式 配置了ReadWriteSplitAspect后,可以根据方法名自动识别操作类型: - 读操作方法(自动使用从库):get、select、query、find、list - 写操作方法(自动使用主库):insert、update、delete、save ## API接口示例 ### 获取用户信息 ```bash GET /user/detail/{id} ``` ### 保存用户信息 ```bash POST /user/saveUser Content-Type: application/json { "userName": "demo", "password": "123456", "email": "demo@example.com" } ``` ## 注意事项 1. 在实际生产环境中,主库和从库应该配置为不同的数据库实例 2. 多数据源环境下需要注意事务一致性问题 3. 从库可能存在数据同步延迟,需要根据业务场景合理选择数据源 4. 可以根据需要扩展支持更多的数据源类型 ## 扩展建议 1. 实现基于权重的数据源选择策略 2. 添加数据源健康检查机制 3. 实现数据源动态扩容和缩容 4. 集成分布式事务管理 ## 许可证 本项目采用Apache License 2.0许可证。详情请查看LICENSE文件。