程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 若依框架
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 若依框架
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • 快速入门

  • 后端手册

    • 分页实现
    • 导入导出功能
    • 文件上传与下载
    • 权限注解实现
    • 事务管理详解
    • 全局异常处理
    • 参数验证详解
    • 数据脱敏详解
    • 系统日志功能实现
    • 数据权限控制
    • 多数据源实现
      • 一、@DataSource 注解参数说明
        • 1. value 参数
      • 二、多数据源的配置与使用
        • 1. 在 application-druid.yml 中配置从库数据源
        • 2. 在 DataSourceType 类中添加数据源枚举
        • 3. 在 DruidConfig 中读取数据源配置
        • 4. 在 DruidConfig 类的 dataSource 方法中添加数据源
        • 5. 使用 @DataSource 注解切换数据源
      • 三、手动切换数据源
      • 四、多数据源配置的逻辑实现
        • 1. DataSourceAspect 切面类
        • 2. 动态数据源路由
      • 五、常见问题与解决方案
        • 1. Service 方法内多个注解无效
        • 2. 配置多个从库
      • 六、总结
    • 代码生成功能
    • 定时任务实现
    • 系统接口文档生成
    • 防重复提交实现
    • 国际化支持
    • 新建子模块
  • 前端手册

  • 组件文档

  • 数据库分析

  • 若依框架
  • 后端手册
scholar
2024-08-31
目录

多数据源实现

# 多数据源实现

在实际开发中,经常遇到需要在一个应用中访问多个数据库的情况。若依框架通过配置多数据源,并使用注解的方式灵活切换数据源,以满足复杂的业务需求。本文将详细介绍在若依框架中如何实现多数据源的配置与使用,并包含注解的使用方法、手动切换数据源的操作,以及常见问题的解决方案。

# 一、@DataSource 注解参数说明

若依框架提供的 @DataSource 注解用于标注需要切换数据源的方法或类。通过配置注解参数,可以指定需要使用的数据源。

参数 类型 默认值 描述
value DataSourceType DataSourceType.MASTER 数据源类型,默认为主库 MASTER

# 1. value 参数

value 参数用于指定数据源的名称。若依框架默认提供了 MASTER 和 SLAVE 数据源类型,开发者可以根据需要自行扩展其他数据源类型。

@DataSource(value = DataSourceType.SLAVE)
public List<SysUser> selectUserList(SysUser user)
{
    return userMapper.selectUserList(user);
}
1
2
3
4
5

# 二、多数据源的配置与使用

# 1. 在 application-druid.yml 中配置从库数据源

首先,需要在 application-druid.yml 文件中配置从库的数据源。若依框架默认使用 Druid 数据库连接池,可以在此处定义多个数据源。

# 从库数据源
slave:
    # 从数据源开关/默认关闭
    enabled: true
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password: password
1
2
3
4
5
6
7

# 2. 在 DataSourceType 类中添加数据源枚举

在 DataSourceType 枚举类中,添加对应的数据源类型枚举值。例如,添加 SLAVE 数据源类型。

public enum DataSourceType
{
    MASTER,  // 主库
    SLAVE    // 从库
}
1
2
3
4
5

# 3. 在 DruidConfig 中读取数据源配置

在 DruidConfig 配置类中,通过 @Bean 注解创建从库的数据源实例,并使用 @ConditionalOnProperty 注解控制从库数据源的启用条件。

@Bean
@ConfigurationProperties("spring.datasource.druid.slave")
@ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")
public DataSource slaveDataSource(DruidProperties druidProperties)
{
    DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
    return druidProperties.dataSource(dataSource);
}
1
2
3
4
5
6
7
8

# 4. 在 DruidConfig 类的 dataSource 方法中添加数据源

在 dataSource 方法中,将从库的数据源添加到目标数据源集合中。

public DataSource dataSource()
{
    Map<Object, Object> targetDataSources = new HashMap<>();
    // 配置主库
    targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource());
    // 配置从库
    targetDataSources.put(DataSourceType.SLAVE.name(), slaveDataSource());
    
    // 动态数据源路由
    DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
    dataSource.setDefaultTargetDataSource(masterDataSource()); // 设置默认数据源
    dataSource.setTargetDataSources(targetDataSources);        // 设置目标数据源
    return dataSource;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 5. 使用 @DataSource 注解切换数据源

在需要使用不同数据源的类或方法上,通过 @DataSource 注解指定数据源。

@DataSource(value = DataSourceType.SLAVE)
public List<SysUser> selectUserList(SysUser user)
{
    return userMapper.selectUserList(user);
}

@Service
@DataSource(value = DataSourceType.SLAVE)
public class SysUserServiceImpl implements ISysUserService
{
    // 服务实现代码
}
1
2
3
4
5
6
7
8
9
10
11
12

# 三、手动切换数据源

在某些复杂场景下,需要在同一方法中手动切换数据源。若依框架提供了 DynamicDataSourceContextHolder 类,支持手动切换数据源。

public List<SysUser> selectUserList(SysUser user)
{
    // 手动切换到从库
    DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE.name());
    
    List<SysUser> userList = userMapper.selectUserList(user);
    
    // 清除数据源设置,恢复默认数据源
    DynamicDataSourceContextHolder.clearDataSourceType();
    
    return userList;
}
1
2
3
4
5
6
7
8
9
10
11
12

# 四、多数据源配置的逻辑实现

多数据源的核心逻辑通过 AOP 切面和动态数据源路由实现。在若依框架中,DataSourceAspect 切面类负责拦截标记了 @DataSource 注解的方法,并动态切换数据源。

# 1. DataSourceAspect 切面类

DataSourceAspect 切面类通过拦截标注了 @DataSource 注解的方法,解析注解参数,并调用 DynamicDataSourceContextHolder 切换数据源。

@Aspect
@Component
public class DataSourceAspect
{
    @Before("@annotation(dataSource)")
    public void beforeSwitchDS(JoinPoint point, DataSource dataSource)
    {
        // 切换数据源
        DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
    }

    @After("@annotation(dataSource)")
    public void afterSwitchDS(JoinPoint point, DataSource dataSource)
    {
        // 清除数据源设置,恢复默认数据源
        DynamicDataSourceContextHolder.clearDataSourceType();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 2. 动态数据源路由

DynamicRoutingDataSource 类通过重写 determineCurrentLookupKey 方法,动态确定当前线程使用的数据源类型。

public class DynamicRoutingDataSource extends AbstractRoutingDataSource
{
    @Override
    protected Object determineCurrentLookupKey()
    {
        // 获取当前线程绑定的数据源类型
        return DynamicDataSourceContextHolder.getDataSourceType();
    }
}
1
2
3
4
5
6
7
8
9

# 五、常见问题与解决方案

# 1. Service 方法内多个注解无效

在 Service 方法内,如果有多个数据源切换注解无效的情况,可能是由于 Spring 的内部方法调用未触发 AOP 代理。解决方法是使用 SpringUtils.getAopProxy(this) 进行代理调用。

public void someServiceMethod()
{
    // 使用 SpringUtils 获取 AOP 代理对象,并调用方法
    SpringUtils.getAopProxy(this).methodWithDataSource();
}
1
2
3
4
5

# 2. 配置多个从库

若依框架支持配置多个从库,开发者可以在 application-druid.yml 中添加多个从库配置,并在 DataSourceType 枚举类中添加对应的数据源类型。

# 从库1数据源
slave1:
    enabled: true
    url: jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password: password

# 从库2数据源
slave2:
    enabled: true
    url: jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password: password
1
2
3
4
5
6
7
8
9
10
11
12
13

# 六、总结

通过配置多数据源并使用 @DataSource 注解,若依框架实现了灵活的多数据源管理,能够轻松应对多库操作的复杂场景。

  • 多数据源配置: 在 application-druid.yml 中配置多个数据源,支持主库和多个从库。
  • 注解切换数据源: 通过 @DataSource 注解在方法或类上切换数据源,简化代码编写。
  • 手动切换数据源: 在复杂场景中,可以使用 DynamicDataSourceContextHolder 类手动切换数据源。
  • 动态数据源路由: 通过 DynamicRoutingDataSource 类实现动态数据源路由,确保数据源切换的灵活性和高效性。
编辑此页 (opens new window)
上次更新: 2024/12/28, 18:32:08
数据权限控制
代码生成功能

← 数据权限控制 代码生成功能→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式