MP 的复杂查询 与其对应的sql

本文探讨如何使用LambdaQueryWrapper和流操作优化查询,通过UserVo类处理班级学生积分,包括SQL查询策略。涉及复制User对象、总分计算及与中间表的交互过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


mmmtypora-copy-images-to: upload

MP 的复杂查询 与其对应的sql

  • 根据classId 进行查询 查询出这个班级的所有学生User的集合 留个后门避免重复测试
  • 返回值是UserVo 是继承User 的一个类 其中多的属性是User 根据不同组进行分类 之后的分数之和
  • 获取User之后 我们要对其进行复制 把其中的属性值复制给UserVo
  • 有两种复制 方法 简单的是遍历 ,复杂的是使用流
    • 三次遍历
      • 第一次遍历 进行复制
      • 第二次遍历 进行总分计算 并进行暂时存储 所以要建立一个HashMap 键值对 分别是组 id 和 组的总分 本质上是模拟中间表
        • 其中要判断组id 是否添加过 如果没有添加过 ,则直接添加
        • 已经添加过,则进行添加
      • 第三次遍历 把计算出来的分数在塞回去 获取组id 之后在从中间表获取数据 进行添加
 //根据id 进行查询
    @Override
    public List<UserVo> findByClassId(Integer classId) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        //后门 根据classId 进行查询
        queryWrapper.eq(User::getClassId, classId == null ? 1 : classId);
        //获取 users 集合
        List<User> users = userMapper.selectList(queryWrapper);

        System.out.println("users = " + users);

        //复制
        ArrayList<UserVo> userVos = new ArrayList<>();
        //遍历原来的集合  取出对象
        for (User user : users) {
            //新建一个新的对象
            UserVo userVo = new UserVo();
            //复制属性  把user对象存入uservo对象
            BeanUtils.copyProperties(user, userVo);
            //在新集合中存入userVos集合中
            userVos.add(userVo);
        }
        //userVos 除了 总分都获取了
        HashMap<Integer, Integer> integralMap = new HashMap<>();
        for (User user : users) {
            //获取组id
            Integer groupId = user.getGroupId();
            //获取积分值
            Integer integral = user.getIntegral();
            //判断该组是否统计过
            if (integralMap.containsKey(groupId)) {
                //已经统计过了
                Integer tempIntegral = integralMap.get(groupId);
                integralMap.put(groupId, tempIntegral + integral);
                continue;
            }
            integralMap.put(groupId, integral);
        }

        //integralMap = {14=0, 15=1, 16=0, 17=-20, 18=2, 19=1, 20=1, 21=10, 22=2, 23=0, 24=-5, 25=0, 26=0, 27=0}
        System.out.println("integralMap = " + integralMap);
        //把总积分 存入 userVos

        for (UserVo userVo : userVos) {
            //获取组id
            Integer groupId = userVo.getGroupId();
            //根据组id 获取组的值
            Integer groupsInterher = integralMap.get(groupId);
            //塞回去
            userVo.setGroupsIntegral(groupsInterher);
        }
        return userVos;
        //使用sql
        //return userMapper.findByClassIdAndjf(classId);
    }
}
  • 简化 流处理
  • List userVos 要进行存储的对象
  • 然后创建一个user的流
  • 在留着进行属性的复制
List<UserVo> userVos = users.stream().map((user) -> {
     UserVo userVo = new UserVo();
     // 复制属性
     BeanUtils.copyProperties(user, userVo);
     return userVo;
 }).collect(Collectors.toList());
 

相对应的sql

  • 是一个复杂查询 一点一点写

  • 在user表中 进行 关于class_id 进行查询 随后进行分组

  • 所需要的数据是组id 和 组分数之和

    • 中间表的查询 对应上面第二个遍历
    SELECT
    	group_id,
    	SUM( integral ) AS groups_integral 
    FROM
    	user
    WHERE
    	class_id = 1
    GROUP BY
    	group_id 
    
  • 将此表作为子表进行查询

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yeU5HHFG-1654583134181)(https://gitee.com/jin-dalong/java-picture/raw/master/picture/202206071416923.png)]

  • 随后 我们要把 上表中的 组分数之和添加到user 表中 并且获取其他几个数据

  • 对两个表进行别名的设置 因为两个表 的groud_id 字段一样

  • 分组条件为 WHERE u.group_id =gi.group_id

  • 并且对其进行限定 class_id 为一个变量 在 代码中 要用#{classId} 进行替换

SELECT
	u.id,
	u.NAME,
	u.mobile,
	u.class_id,
	u.group_id,
	u.group_name,
	u.integral, 
    gi.groups_integral
FROM USER AS u,
(SELECT
	group_id,
	SUM( integral ) AS groups_integral 
FROM
	user
WHERE
	class_id = 1
GROUP BY
	group_id ) gi
	WHERE u.group_id =gi.group_id
	   AND u.role_id = 2
		    AND u.class_id = 1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O14xWLav-1654583134182)(https://gitee.com/jin-dalong/java-picture/raw/master/picture/202206071416924.png)]

SELECT
    u.id,
    u.NAME,
    u.mobile,
    u.class_id,
    u.group_id,
    u.group_name,
    u.integral,
    gi.group_integral  groups_integral
FROM
    USER AS u,
    ( SELECT group_id, SUM( integral ) AS group_integral FROM `user` WHERE class_id = 1 GROUP BY group_id ) AS gi
WHERE
    u.group_id = gi.group_id
  AND u.class_id = #{classId}
  AND u.role_id = 2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gold 大龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值