MybatisPlus 关联查询方案

SpringBoot和Mybatis-Plus整合实现关联查询 1.创建Maven普通项目2.添加依赖坐标3.导入SpringBoot的相关插件4.创建mapper包、pojo包和启动类Startermapper包:在该包下定接口继承BaseMapper接口pojo包:在该包下定义实体类:客户类、商品类、订单类和订单详情类Starter类:用于SpringBoot项目启动运行5.在resources文件下配置yml文件(数据库配置和日志配置)6.在resources文件下创建mapper文件夹,在mapper下创建XML文件自定义数据库操作功能实现。 阅读详情

Mybatis-Plus 简介

什么是 MyBatis-Plus?Mybatis-Plus:为简化开发而生

MyBatis-Plus(简称 MP)是一个基于 MyBatis 的增强工具,它对 Mybatis 的基础功能进行了增强,但未做任何改变。使得我们可以可以在 Mybatis 开发的项目上直接进行升级为 Mybatis-plus,正如它对自己的定位,它能够帮助我们进一步简化开发过程,提高开发效率。

Mybatis-Plus 其实可以看作是对 Mybatis 的再一次封装,升级之后,对于单表的 CRUD 操作,调用 Mybatis-Plus 所提供的 API 就能够轻松实现,此外还提供了各种查询方式、分页等行为。最最重要的,开发人员还不用去编写 XML,这就大大降低了开发难度

官网:https://mp.baomidou.com

连表?Left Join?Inner Join?

MybtaisPlus 极大简便了单表的操作,但对应连表查询更多的还是在xml中实现,本人是一个单表主义者(能单表,尽量不连表),阿里的相关规范中也提到:尽量使用单表,连表尽量不要超过3张,于是更多的时候,是把主表查询处理,然后使用流处理把关联的表Id集合起来,再通过listByIds转toMap,得到Id对应的对象,再进行get相对应赋值,最初也没啥,当写的越来越多了之后,问题就开始暴露了,没错,代码实在是太长,太臭啦!!!

旧版代码

Set<Long> systemProjectFileSecurityIdSet = records.stream().map(SystemProjectFileSecurityGroupSetting::getSystemProjectFileSecurityId).collect(Collectors.toSet());
Map<Long, SystemProjectFileSecurity> systemProjectFileSecurityMap = new HashMap<>();
if (!systemProjectFileSecurityIdSet.isEmpty()) {
            systemProjectFileSecurityMap.putAll(systemProjectFileSecurityService.listByIds(systemProjectFileSecurityIdSet)
                    .stream()
                    .collect(Collectors.toMap(SystemProjectFileSecurity::getSystemProjectFileSecurityId, systemProjectFileSecurity -> systemProjectFileSecurity)));
}

旧版代码太长了啦,每次关联,都需要5-7行,一张业务表少说也有3到5个表关联,这样编写的话,显得代码太过累赘,以及冗余,整体看的实在太难受啦

新版优化

//如果你当前的数据里面有 明确目标表 的id,那请用 linkXxx;(你有目标表的id)
Map<Long, SystemProjectFileSecurity> systemProjectFileSecurityMap = 
    linkTableUtils.linkSystemProjectFileSecurity(records, SystemProjectFileSecurityGroupSetting::getSystemProjectFileSecurityId);
//如果你只有你自己的id,目标表存储你的id,那请用 xxxLink;(目标表有你id)
Map<Long, ModelProjectStaffing> map = 
    linkTableUtils.modelProjectStaffingLink(ModelProjectStaffing::getProjectId, projectList, Project::getProjectId,Collectors.toMap(ModelProjectStaffing::getProjectId, data->data));

我们对冗余的代码进行的抽取,目前1-2行就可以实现5-7行的功能,就算关联查询更多的表,代码看起来也更整洁,嗯,真香

相关工具类

import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 链接其他表的工具类
 * 情景一:如果你当前的数据里面有 明确目标表 的id,那请用 linkXxx;(你有目标表的id)
 * linkXxx 执行效果类似  select * from targetTable where targetTable.id in (xxx,xxx,xxx)
 * 情景二:如果你只有你自己的id,目标表存储你的id,那请用 xxxLink;(目标表有你id)
 * xxxLink 执行效果类似  select * from targetTable where targetTable.otherTableId in (xxx,xxx,xxx)
 *
 * @author zengqinghua
 */
@Component
public class LinkTableUtils {

    /**
     * 链接 XXX表
     */
    public <T> Map<Long, SystemProjectFileSecurity> linkSystemProjectFileSecurity(List<T> records, Function<T, Long> getKey) {
        return this.linkTable(TableEnum.SystemProjectFileSecurity, records, getKey, SystemProjectFileSecurity::getSystemProjectFileSecurityId);
    }


    /**
     * xxx表 链接
     */
    public <T, R> R modelProjectStaffingLink(SFunction<ModelProjectStaffing, Long> targetKey, List<T> records, Function<T, Long> sourceKey, Collector<ModelProjectStaffing, ?, R> collector) {
        return this.tableLink(TableEnum.ModelProjectStaffing, targetKey, records, sourceKey, collector);
    }

    /**
     * 链接 表(通用方法)
     *
     * @param tableEnum 表名枚举
     * @param records   数据源列表
     * @param getKey    查询的Id
     * @param getRKey   map的key
     * @param <T>       数据源泛型
     * @param <R>       目标结果泛型
     * @return
     */
    public <T, R> Map<Long, R> linkTable(
            TableEnum tableEnum,
            List<T> records, Function<T, Long> getKey,
            Function<R, Long> getRKey
    ) {
        if (records.isEmpty()) {
            return new HashMap<>();
        }

        // 得到对应的id
        Set<Long> idSet = records.stream().map(getKey).collect(Collectors.toSet());
        if (idSet.isEmpty()) {
            return new HashMap<>();
        }

        IService<R> iService = (IService) ApplicationContextUtil.getBean(tableEnum.tClass);
        return iService.listByIds(idSet)
                .stream()
                .collect(Collectors.toMap(getRKey, data -> data));
    }

    /**
     * 链接 表(通用方法)
     *
     * @param tableEnum         表名枚举
     * @param targetSearchField 目标查询的字段
     * @param records           数据源列表
     * @param sourceField       数据源字段
     * @param <T>               数据源泛型
     * @param <T2>              目标泛型
     * @param <R>               结果泛型
     * @return
     */
    public <T, T2, R> R tableLink(
            TableEnum tableEnum,
            SFunction<T2, Long> targetSearchField,
            List<T> records, Function<T, Long> sourceField,
            Collector<T2, ?, R> collector
    ) {
        if (records.isEmpty()) {
            return (R) collector.supplier().get();
        }

        // 得到对应的id
        Set<Long> idSet = records.stream().map(sourceField).collect(Collectors.toSet());
        if (idSet.isEmpty()) {
            return (R) collector.supplier().get();
        }

        IService<T2> iService = (IService) ApplicationContextUtil.getBean(tableEnum.tClass);
        return iService.list(Wrappers.<T2>lambdaQuery()
                .in(targetSearchField, idSet))
                .stream()
                .collect(collector);
    }

    public enum TableEnum {
        SystemProjectFileSecurity("xxxx", ISystemProjectFileSecurityService.class),
        ModelProjectStaffing("xxx", IModelProjectStaffingService.class),
        ;

        private final String tableRemark;
        private final Class tClass;

        TableEnum(String tableRemark, Class tClass) {
            this.tableRemark = tableRemark;
            this.tClass = tClass;
        }
    }
}
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

@Component
@Lazy(false)
public class ApplicationContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (ApplicationContextUtil.applicationContext == null) {
            ApplicationContextUtil.applicationContext = applicationContext;
        }
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * 根据bean名称获取指定类型bean
     *
     * @param beanName bean名称
     * @param clazz    返回的bean类型,若类型不匹配,将抛出异常
     */
    public static <T> T getBean(String beanName, Class<T> clazz) {
        return getApplicationContext().getBean(beanName, clazz);
    }
}

活用QueryWrapper与@Select注解,构建MybatisPlus动态多表查询方案 本文深入探讨了如何结合MybatisPlus的QueryWrapper与@Select注解,构建高效灵活的动态多表关联查询方案。通过解析${ew.customSqlSegment}占位符机制,并设计通用的Service层封装,解决了复杂条件下多表查询的SQL拼接难题,显著提升了后台管理系统列表查询的开发效率与可维护性。 阅读详情

相关推荐

MyBatisPlus实战:QueryWrapper处理复杂关联查询的3种姿势(含代码示例)

本文深入探讨了MyBatisPlus中QueryWrapper处理复杂关联查询的三种核心方法。针对一对一、一对多、多对多等典型场景,通过详实的代码示例,对比了单次JOIN查询与分步查询的优劣,并提供了性能优化与N+1问题的解决方案,帮助开发者编写更清晰、高效且易于维护的数据查询代码。

weixin_29204205的博客 144

MybatisPlus联合查询

目录1、什么是Mybatis-plus-join?2、下载Mybatis-plus-join3、离线版请使用Maven将其打包成jar包3.1、使用idea打包4.项目中引用Mybatis-plus-join的pom.xml配置5、在业务中使用mybatis-plus-join的准备使用核心类 MPJLambdaWrapper和MPJQueryWrapperMPJLambdaWrapper用法MPJLambdaWrapper示例简单的3表查询分页查询MPJQueryWrapper简单的3表查询分页查询还可以

赵广陆 3万+

MybatisPlus QueryWrapper使用陷阱与LambdaQuery最佳实践

在Java持久层开发中,ORM框架的查询构造器是提高开发效率的关键组件。MybatisPlus作为Mybatis增强工具,其QueryWrapper通过链式调用简化了条件构造,但在与@Select注解混用时可能引发SQL注入、条件冲突等问题。LambdaQueryWrapper通过方法引用实现类型安全查询,配合Service层的lambdaQuery()方法,既能避免拼写错误又提升代码可读性。本文深入解析QueryWrapper的常见副作用,包括SQL注入风险、性能优化策略,并推荐使用LambdaQuery

weixin_31309419的博客 305

MyBatis-Plus多表关联查询

有两张表:用户表(User)、区域表(Area),其中用户表里通过 area_id 字段关联区域表的 id 主键:测试。

我的博客 1万+

从零到一:MyBatisPlus与Thymeleaf分页实战中的性能优化秘籍

本文详细解析了MyBatisPlus与Thymeleaf在全栈开发中的高性能分页方案,通过游标分页、延迟关联等深度整合技术,实现毫秒级响应。涵盖从后端查询优化到前端渲染的全链路性能提升策略,适用于大数据量场景下的分页需求。

weixin_29299807的博客 233

MyBatis Plus多表关联查询详解

通过以上步骤,我们成功地实现了在MyBatis Plus中进行多表关联查询的功能。在实际项目中,我们可以根据具体需求,灵活运用MyBatis Plus提供的API来完成更复杂的多表关联查询操作。希望本文能对你理解MyBatis Plus多表关联查询有所帮助。【完】

理论都是虚的,代码才是王道。 2783

MybatisPlus多表关联查询

maven文件 实体转Vo 持久层方法 补充信息方法 1.2、查询多条记录 持久层方法 补充信息方法 1.3、分页列表 持久层方法 补充信息方法 二、一对多查询 2.1、查询单条记录 2.2、查询多条数据 2.3、分页列表 三、多对多查询 3.1、查询单条记录 3.2、查询多条数据 3.3、分页列表......

Java日常记录 7156

MybatisPlus多表关联分页查询

Mybatis-plus的多表关联查询的参数,可以使用LambdaQueryWrapper或QueryWrapper加入多个表查询条件,并使用Join方法进行关联。Mybatis-plus是一个Mybatis的增强工具,提供了许多功能强大的API,其中包括分页查询和多表关联查询。在Mybatis-plus中,连表查询可以使用LambdaQueryWrapper或QueryWrapper加入多个表进行查询,然后再使用IPage进行分页。

Mr.xing的博客 5811

MybatisPlus在用Collection标签查询时List中只出现一条记录

2.确定子表的主键字段,由于主表与子表为一对多的关系,在建立子表时很有可能没有指定子表主键,故在解决此问题时需要把collection标签中的。1.mybatisPlus在collection关联子表的情况下,如果主表主键ID的字段名与子表的主键ID字段一样的话,需要别名子表id字段。在用mybatisPlus做关联查询时,发现list集合中只能显示出一条数据,且总是保持为第一条,而mybatis日志打印都是正确的。注意:column对应的是表字段名,别名之后应与别名保持一致。

weixin_50324259的博客 2921

以太网接口及POE设计

PoE标准 Power Over Ethernet 是有源以太网供电的简称 通过Cat-5电缆供电在IEEE 802.3af以太网供电标准中进行了定义。PoE标准以前限制在几瓦以内,但更新的PoE技术可实现更高的功率。例如,PoE+允许每端口功率高达25 W,而PoE++(四 对以太网供电系统)通过使用现有电缆的所有电线允许70 W到100 W的功率。与此PoE标准并行的是ADI公司定义的专有标准 LTPoE++™,该标准定义高达90W的受电设备(PD)功率规范(请参见表1)。 表1. ADI...

u010783226的专栏 1万+

PIC单片机应用开发实践教程(二): 新建工程

File---New ProjectMicrochip Embedded --- Standalone Project 选择所用MCU对应型号 点击 Finish 后,工程就建好了 至止,我们的一个新工程就建完成了!

qq_57798018的博客 2888

MyBatis + MyBatisPlus 中遇到的一些坑

坑叨叨坑一:MyBatisPlus分页不生效坑二:一对多关联查询查询总条数错误 叨叨 MyBatis是很常用的持久层框架,MyBatisPlus是一个 MyBatis 的增强工具.在实际工作中这两者就像是咖啡伴侣一样如影随形. 但是总会遇到这样或那样的问题,可能是一个失误,也可能是踩了个坑 坑一:MyBatisPlus分页不生效 自己没开启分页插件,是谁更坑呢? @Configuration ...

我的博客 6250

用ST25DV芯片+KiCad快速设计NFC标签天线:参数计算/脚本生成/实测优化全流程

本文详细介绍了使用ST25DV芯片和KiCad工具设计NFC标签天线的全流程,包括参数计算、脚本生成和实测优化。通过解析芯片等效工作原理和设计思路,帮助开发者避开常见陷阱,实现高效、可量产的天线设计。文章还提供了Python计算工具和KiCad自动化脚本,大幅提升设计效率和成功率。

jj890的博客 756

MyBatisPlus分页查询数据量过大导致查询过慢

项目中存在一张订单表(1000万数据),现有需求新增一个查询页面,需要关联用户表,商品表查询数据,分页展示。

qq_44896640的博客 1597

8155平台multi-display(多屏显示)原理与配置

8155平台多屏互动原理与配置

漂流瓶の海岸 1603

python实现边缘检测Canny算子 (附完整源码)

python实现边缘检测Canny算子 (附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 456

MyBatis Plus 如何支持一对多的查询场景

MyBatis Plus是一个强大的MyBatis增强工具,它提供了许多方便的功能,如注解支持、缓存机制等。以上是MyBatis Plus支持一对多查询场景的一些常见方法,具体实现方式可能因具体场景而异。根据实际情况选择适合的方法可以提高查询性能和代码的可维护性。属性指定了关联对象(用户)的属性名,在上面的示例中,使用了SQL语句中的。属性指定了用户对象的订单属性名,属性指定了关联对象的实体类名。属性指定了订单对象的实体类名。标签定义了返回的结果集,其中。在上面的示例中,通过调用。

qq_33240556的博客 1878

Allegro基本规则设置指导书之Spacing Region

当网络需要在Region中需要按照自身的规则匹配时,可以创建Region Class来匹配。Region也支持Class to Class规则,点击ok即可。Allegro基本规则设置指导书之Spacing Region。下面介绍基本规则设置指导书之Spacing Region。给创建好的Region 匹配一个规则。空白的地方创建一个Region。

weixin_54787054的博客 563

Qwen3-VL优化MyBatisPlus关联查询性能

利用通义千问Qwen3-VL大模型辅助分析MyBatisPlus关联查询性能问题,通过SQL、执行计划与表结构的智能推理,自动识别N+1查询、索引缺失等瓶颈,并生成可落地的优化建议,提升数据库查询效率与开发体验。

weixin_30021053的博客 848

MATLAB与ROS联合仿真——ROS环境搭建及相关准备工作(上)

本篇文章主要介绍在安装完ROS后,在进行MATLAB与ROS联合仿真之前,需要进行的一些环境搭建以及准备工作,主要分为 创建ROS工作空间及功能包、必备功能包安装、安装Gazebo11、导入实验功能包至工作空间、安装Visual_Studio_Code(选做)、常用便捷工具安装(选做) 六部分。    本部分内容共分为上下两篇,上篇包括创建ROS工作空间及功能包和必备功能包安装这两部分,下篇包括、安装Gazebo11、导入实验功能包至工作空间、安装Visual_Studio_Code(选做)、常用便捷工

慕羽★的博客 3361

芒果YOLO11改进145:Loss损失函数KLD:即插即用 NeurIPS顶会论文,独家首发原创新颖|通过 Kullback-Leibler 散度学习用于目标检测的高精度边界框

旋转检测Loss损失函数KLD:即插即用 NeurIPS顶会论文,独家首发原创新颖|通过 Kullback-Leibler 散度学习用于目标检测的高精度边界框

包括YOLOv5、YOLOv7、YOLOv8等模型改进 565

MybatisPlus多表查询

一定要生成get、set,否则Result中的orders拿不到selectByUid方法的返回值【没有set方法】简单对应order_t表加上get、set即可,主键id最好用Integer类型。指定非表中数据【exist=false】,生成get、set。注意订单表不要直接取名order会与SQL关键字冲突。接下来首先来实现查询用户的时候把其所有订单查出来。接下来实现查询订单的时候把其用户一起查出来。这里的@Resuts等于是做了一个拼接。

W2398439780的博客 1723

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

MyBatis Plus对关联查询一对多 分页不准确问题解决

今天在和前端联调的时候,突然被告知接口分页有问题,不准确,随后debug发现的确如此: xml代码: <resultMap id="getRoleInfoMap" type="com.lylb.casecenter.entity.vo.RoleVO"> <id column="roleId" property="id"/> <result column="roleName" property="name"/> <co

Mr_Xyong的博客 3452

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

记录mybatisPlus使用自定义分页查询后分页不生效的问题

mybatisPlus自定义分页查询,分页不生效问题

My_csdo的博客 803

避开这些坑!QueryWrapper关联查询中的5个常见错误及解决方案

本文详细解析了MyBatisPlus中QueryWrapper关联查询的5个常见错误及解决方案,包括字段映射不完整、N+1查询性能问题、动态条件拼接风险、分页总数计算错误以及多对多关联中间表忽略。通过实际案例和代码示例,帮助开发者避免这些陷阱,提升查询效率和安全性。

weixin_29199873的博客 289

MybatisPlus逻辑删除全解析:从原理到实践,避坑指南

在数据库操作中,删除数据是一个关键且敏感的操作。物理删除虽然能彻底移除数据,但存在数据不可恢复、破坏关联性和无法满足审计要求等风险。因此,逻辑删除作为一种以空间换安全的智慧方案应运而生,它通过一个标志位(如is_deleted)来标记数据状态,实现“假删除”。其技术价值在于保障数据安全、保持数据完整性和支持操作可逆,广泛应用于需要数据追溯、审计和恢复的业务场景,如用户管理、订单系统等。MybatisPlus框架对逻辑删除提供了优雅的开箱即用支持,通过全局配置或@TableLogic注解即可轻松实现。本文将结

weixin_34166472的博客 503
上一篇: centos7 安装 nacos (复制粘贴系列)
下一篇: 若依VUE前端打包,nginx非根目录404解决
97牛肉面
博客等级 码龄9年 54粉丝 75原创
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值