common-datasource 多数据源使用

模块简介

PigX 的多数据源配置,基于 dynamic-datasource-spring-boot-starter 实现,理论上支持此组件的全部功能。

事务注意事项

动态数据源操作不要添加 @Transactional 注解,会导致数据源切换失效

使用步骤

业务服务引入依赖

在需要使用多数据源的微服务模块中添加依赖:

<dependency>
  <groupId>com.pig4cloud</groupId>
  <artifactId>pigx-common-datasource</artifactId>
</dependency>

开启动态数据源

在启动类上添加 @EnableDynamicDataSource 注解:

// 注意此注解放在所有注解之上,单体架构放在 pigx-boot 模块 Main 方法上
@EnableDynamicDataSource
@SpringBootApplication
public class App {
	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}
}
注解位置

@EnableDynamicDataSource 注解需要放在所有注解之上

配置数据源

方式一: YAML 维护数据源

版本要求

此功能在 v5.7+ 版本中可用

在微服务对应的 Nacos 配置文件中添加如下配置,如 nacos/pigx-upms-biz-dev.yaml:

spring:
  # 数据库相关配置
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid: # 主数据源 (原有的不需要修改)
      driver-class-name: com.mysql.cj.jdbc.Driver
      username: root
      password: root
      url: 指向默认的 PIGX 数据库
    dynamic:  # 扩展的数据源
      datasource:
        ext1:  # 扩展数据源1
          type: com.alibaba.druid.pool.DruidDataSource
          driver-class-name: com.mysql.cj.jdbc.Driver
          username: root
          password: root
          url: 指向默认的扩展数据库1
          druid:
            proxy-filters: sqlLogFilter # 指定数据源SQL 打印
配置格式

扩展数据源配置在 spring.datasource.dynamic.datasource 节点下,每个数据源使用唯一的名称标识

方式二: 数据库配置数据源

在主数据源创建 gen_datasource_conf 表,从数据库加载其他数据源信息:

DROP TABLE IF EXISTS `gen_datasource_conf`;
CREATE TABLE `gen_datasource_conf` (
  `id` bigint NOT NULL COMMENT '主键',
  `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '别名',
  `url` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'jdbcurl',
  `username` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户名',
  `password` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '密码',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新',
  `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记',
  `tenant_id` bigint DEFAULT NULL COMMENT '租户ID',
  `ds_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数据库类型',
  `conf_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '配置类型',
  `ds_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数据库名称',
  `instance` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '实例',
  `port` int DEFAULT NULL COMMENT '端口',
  `host` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '主机',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='数据源表';
表创建位置

gen_datasource_conf 表需要在主数据源创建,系统启动时会自动加载此表中的数据源配置

使用动态数据源查询

Mapper 层添加 @DS("#last") 注解,最后一个参数为指定数据源(必须有):

@Mapper
public interface DemoMapper extends BaseMapper<Demo> {
	@DS("#last")
	Map selectDs(String dsName);
}

Service 层调用:

@Service
public class DemoServiceImpl extends ServiceImpl<DemoMapper, Demo> implements DemoService {
	@Override
	public Object getByDs(Integer id) {
		// 此处 dsName 为以上 gen_datasource_conf 加载数据源 name 字段
		return baseMapper.selectDs("pigxx_core");
	}
}
参数位置

@DS("#last") 表示使用方法的最后一个参数作为数据源名称,确保调用时传入正确的数据源标识

扩展使用

参考 官方文档: 动态参数解析数据源

从 Session 获取数据源

@DS("#session.tenantName")
public List selectSpelBySession() {
	return userMapper.selectUsers();
}

从 Header 获取数据源

@DS("#header.tenantName")
public List selectSpelByHeader() {
	return userMapper.selectUsers();
}

从参数获取数据源

@DS("#tenantName")
public List selectSpelByKey(String tenantName) {
	return userMapper.selectUsers();
}

从复杂参数获取数据源

@DS("#user.tenantName")
public List selectSpelByTenant(User user) {
	return userMapper.selectUsers();
}
SpEL 表达式

@DS 注解支持 Spring EL 表达式,可以灵活地从不同来源获取数据源标识