logo 范 · 拾光录
网址收集 关于作者 Github Gitee
杂文随笔4
Hexo博客:基础使用Hexo博客:Next主题Hexo博客:Next进阶使用Hexo博客:Next高级配置
前端编程3
前端基础知识16
Vue框架19
UniApp15
Java编程8
Java基础知识14
SpringBoot35
SpringMVC15
MyBatis9
Spring Cloud Netflix8
Spring Cloud Alibaba7
RocketMQ1
MyCat1
数据库4
MySQL12
Redis8
MongoDB10
H21
Java技术栈1
分布式锁的实现方案
软件工具箱14
IDEAGitMavenGradleNginx安装Nginx配置JMeter压测OllamaPicGoRustFSVSCodeDockerObsidianObs录制
Linux知识11
Linux常用命令Jar启动脚本VirtualBox安装CentOSVirtualBox安装Ubuntu树莓派安装及使用frp内网穿透ArchLinux:常用软件ArchLinux:基础系统安装ArchLinux:深度优化ArchLInux:图形化界面安装ArchLinux:Niri
Python编程6
Python基础知识Python语法yolo目标检测OpenCV的使用及树莓派平台condauv
AI相关9
Claude CodeHermes AgentOpenAI基本使用OpenAI工具调用OpenAI记忆管理OpenAI推理执行OpenAI开发框架Langchainllama.cpp
创意设计2
Blender:入门知识UI设计基础知识

增加

原则:先查用户,再查中间表。使用 saveBatch 批量插入中间表高效

@Transactional // 记得加事务
public void addUserWithRoles(User user, List<Long> roleIds) {
    // 1. 保存用户
    userMapper.insert(user);
    // 2. 批量插入中间表
    if (CollUtil.isNotEmpty(roleIds)) {
        List<UserRole> list = roleIds.stream()
            .map(rid -> new UserRole(user.getId(), rid))
            .collect(Collectors.toList());
        userRoleMapper.insertBatchSomeColumn(list); // 需配置批量插件
    }
}

删除

原则:删除中间表关联,可选是否删用户主表

@Transactional
public void removeUserRoles(Long userId, List<Long> roleIds) {
    // 构造删除条件:用户ID + 角色ID列表
    LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(UserRole::getUserId, userId)
           .in(UserRole::getRoleId, roleIds);
    userRoleMapper.delete(wrapper);
    
    // 若需删除用户主表:userMapper.deleteById(userId);
}

修改

原则:先删后增,简单可靠,无需比对差异

@Transactional
public void updateUserRoles(Long userId, List<Long> newRoleIds) {
    // 1. 删除该用户所有旧关联
    LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(UserRole::getUserId, userId);
    userRoleMapper.delete(wrapper);
    
    // 2. 插入新关联(复用“增”的批量逻辑)
    if (CollUtil.isNotEmpty(newRoleIds)) {
        // ...批量插入代码同上
    }
}

查询

分步执行,查询2次数据库

public List<User> getUsersWithRoles() {
    // 1. 查所有用户
    List<User> users = userMapper.selectList(null);
    if (CollUtil.isEmpty(users)) return users;
    
    // 2. 提取所有userId,批量查中间表和角色
    List<Long> userIds = users.stream().map(User::getId).collect(Collectors.toList());
    // 连表查询:SELECT u.*, r.* FROM user_role ur LEFT JOIN role r ON ur.role_id = r.id WHERE ur.user_id IN (...)
    List<UserRoleDTO> mappings = userRoleMapper.selectRoleListByUserIds(userIds);
    
    // 3. 组装到User对象(按userId分组)
    Map<Long, List<Role>> map = mappings.stream()
        .collect(Collectors.groupingBy(UserRoleDTO::getUserId, 
                 Collectors.mapping(dto -> new Role(dto.getRoleId(), dto.getRoleName()), toList())));
    users.forEach(u -> u.setRoles(map.getOrDefault(u.getId(), emptyList())));
    return users;
}
增加
删除
修改
查询