多数据源配置及使用,在同一个方法下切换数据源。

切换数据源方法:

  1. 通过注解切换数据源,可以在方法上使用也可以在类上使用,遵循就近原则

@DS("数据源名")

注意:在同一个方法使用多个数据源不要使用@Transactional,会导致报错。

  1. 方法中手动切换

切换数据源类似压栈,弹栈操作。引入依赖和配置文件见示例。

复制代码
//引入jar包
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;

@Override
public OperaResponse testSelectCompanyAndUser() {
    //方法体内部
    //切换数据源
    DynamicDataSourceContextHolder.push("mysql1");
    //数据操作

    //释放数据源
    DynamicDataSourceContextHolder.poll();

    //切换数据源
    DynamicDataSourceContextHolder.push("mysql2");
    //数据操作

    //释放数据源
    DynamicDataSourceContextHolder.poll();
    return OperaResponse.ok();
}

示例使用场景,使用方法1

将测试服务器的企业与用户的关联关系映射到本地服务器中。

本例在mapper类上使用@DS切换数据源

引入依赖

复制代码
<properties>        
    <dynamic-datasource.version>3.5.0</dynamic-datasource.version>
</properties>

<!-- Mybatis-plus多数据源 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>${dynamic-datasource.version}</version>
</dependency>

配置文件yml

复制代码
datasource:
    dynamic:
      primary: mysql1 #设置默认的数据源或者数据源组,默认值即为mysql1
      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      datasource:
        mysql1: # 数据源名
          driverClassName: com.mysql.cj.jdbc.Driver
          url: 数据源地址?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
          username: 用户名
          password: 密码
        mysql2: # 数据源名
          driverClassName: com.mysql.cj.jdbc.Driver
          url: 数据源地址?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
          username: 用户名
          password: 密码
    # 以下非必须,配置数据库连接池
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      connection-timeout: 30000       # 等待连接池分配连接的最大时长(毫秒),超过这个时长还没可用的连接则发生SQLException, 默认:30秒
      minimum-idle: 5                 # 最小连接数
      maximum-pool-size: 20           # 最大连接数
      auto-commit: true               # 自动提交
      idle-timeout: 600000            # 连接超时的最大时长(毫秒),超时则被释放(retired),默认:10分钟
      pool-name: DateSourceHikariCP     # 连接池名字
      max-lifetime: 1800000           # 连接的生命时长(毫秒),超时而且没被使用则被释放(retired),默认:30分钟 1800000ms
      connection-test-query: SELECT 1

Mapper.java

复制代码
@Repository
@DS("mysql2")
public interface CompanyUserMapper extends BaseMapper<CompanyUser> {
}

UserService.java

复制代码
public interface IUserService extends IService<User> {
    /**
     * 将测试服务器的企业与用户的关联关系映射到本地服务器中
     *
     * 多数据源中@Transactional(rollbackFor = Exception.class) 事务失效并会导致切换数据源报错
     * @DS("mysql1"),@DS("mysql1")切换数据源可以在方法上使用,也可以在类上使用。
     *     如在mapper类或方法上使用,或在serviceImpl类或方法上使用。
     * @return
     */
    OperaResponse CompanyAndUserMapping();
}

UserServiceImpl.java

复制代码
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private CompanyUserMapper companyUserMapper;

    @Override
    public OperaResponse CompanyAndUserMapping() {
        //查询所有企业部门用户信息
        List<CompanyUser> companyUserList = companyUserMapper.selectList(new QueryWrapper<>());
        //将企业部门用户信息根据用户id进行分组
        Map<Long, List<CompanyUser>> map = companyUserList.stream().collect(Collectors.groupingBy(CompanyUser::getUserId));

        List<User> userList = this.list();
        //将企业id映射到用户表中
        for(User user : userList){
            if(map.containsKey(user.getId())){
                List<CompanyUser> companyUserList1 = map.get(user.getId());
                if(CollectionUtils.isEmpty(companyUserList1)){
                    return OperaResponse.error(ErrStatus.ERR_COMPANY);
                }
                if(companyUserList1.size() > 1){
                    log.info("用户id为:" + user.getId() + "的用户存在多个企业。"+"企业信息为:"+ companyUserList1.toString());
                }
                user.setCompanyId(companyUserList1.get(0) == null ? null : companyUserList1.get(0).getCompanyId());
                //更新用户信息
                this.updateById(user);
            }
        }
        return OperaResponse.ok();
    }
}

UserController.java

复制代码
@RestController
@RequestMapping("/management/user")
public class UserController {

    @Autowired
    private IUserService userService;
 
   /**
     * 将测试服务器的企业与用户的关联关系映射到本地服务器中
     *
     * 多数据源中@Transactional(rollbackFor = Exception.class) 事务失效并会导致切换数据源报错
     * @DS("mysql1"),@DS("mysql1")切换数据源可以在方法上使用,也可以在类上使用。
     *     如在mapper类或方法上使用,或在serviceImpl类或方法上使用。
     * @return
     */
    @GetMapping("/CompanyAndUserMapping")
    @WebLog(description = "映射企业与用户关系")
    public OperaResponse CompanyAndUserMapping(){
        return userService.CompanyAndUserMapping();
    }
}
相关推荐
jackson凌5 分钟前
【Java学习笔记】选择结构
java·笔记·学习
极客先躯8 分钟前
高级java每日一道面试题-2025年4月21日-基础篇[反射篇]-如何使用反射获取一个类的所有方法?
java·面试·反射·基础篇
亚力山大抵9 分钟前
实验2 python的TCP群聊系统实现
服务器·python·tcp/ip
掉鱼的猫12 分钟前
开发 MCP Proxy(代理)也可以用 Solon AI MCP 哟!
java·mcp
佩奇的技术笔记14 分钟前
Java学习手册:HTTP 协议基础知识
java·http
博弈美业系统Java源码17 分钟前
连锁美业管理系统「数据分析」的重要作用分析︳博弈美业系统疗愈系统分享
java·大数据·前端·后端·创业创新
秋野酱17 分钟前
基于javaweb的SpringBoot扶农助农平台管理系统设计与实现(源码+文档+部署讲解)
java·spring boot·后端
涛思数据(TDengine)17 分钟前
时序数据库 TDengine 助力石油石化业务, 平滑接替 Oracle 数据库
数据库·时序数据库·tdengine
学术小八23 分钟前
穿越链路的旅程:深入理解计算机网络中的数据链路层
linux·服务器·网络
暮乘白帝过重山30 分钟前
为什么Spring中@Bean注解默认创建单例Bean
java·spring