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

切换数据源方法:

  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();
    }
}
相关推荐
Zzzzzxl_19 小时前
互联网大厂Java/Agent面试实战:微服务、RAG与Agent化实战(含答疑解析)
java·jvm·spring boot·agent·milvus·rag·microservices
wanhengidc19 小时前
云手机 高算力 快速便捷
运维·服务器·科技·游戏·智能手机
饕餮争锋19 小时前
Linux 常用命令分类详解
linux·运维·服务器
咖丨喱19 小时前
【修复miracast协商失败问题】
服务器·数据库·asp.net
蟹至之19 小时前
【MySQL】索引 (上) —— 索引的定义与数据结构
数据库·mysql·索引
·云扬·19 小时前
基于YCSB的MongoDB性能压测实践指南
数据库·mongodb
卿雪19 小时前
MySQL【索引】:索引的概念与分类
java·数据库·python·mysql·adb·golang
kong@react19 小时前
springbpoot项目,富文本,xss脚本攻击防护,jsoup
java·前端·spring boot·xss
Zzzzzxl_19 小时前
互联网大厂Java/Agent面试实战:Spring Boot、JVM、微服务、Kafka与AI Agent场景问答
java·jvm·spring boot·redis·ai·kafka·microservices
wanhengidc19 小时前
云手机如何进行数据备份
运维·服务器·科技·智能手机·云计算