MyBatis-Plus实现多表联查方式(一对一,一对多使用)

 更新时间:2025年10月15日 09:59:47   作者:慷 慨  
文章介绍了MyBatis-Plus-Join插件,一个在MyBatis-Plus基础上增强的工具,支持联表查询而不改变原有代码结构,MPJ插件无侵入性,兼容MyBatis-Plus的多种特性,并支持注解形式的一对一和一对多查询

1、前言

在使用mybatis-plus开发需求的时候会发现对于大部分的业务场景来说都会使用到join来进行联表查询,但是mybatis-plus封装的 mapper 不支持 join,如果需要支持就需要自己手动去实现,给大家推荐一个好用的插件(MyBatis-Plus-Join)。

2、介绍

Mybatis-Plus-Join(简称 MPJ)是一个 Mybatis-Plus的增强工具,在 MyBatis-Plus 的基础上只做增强不做改变,为简化开发、提高效率而生。

3、特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 无感引入, 支持MP风格的查询, 您会MP就会MPJ, 无需额外的学习成本
  • 兼容MP的别名、逻辑删除、枚举列、TypeHandle列等特性
  • 支持注解形式一对一、一对多和连表查询形式的一对一和一对多

4、使用

引依赖

需要 Mybatis-plus version >= 3.4.0

<dependency>
            <groupId>com.github.yulichang</groupId>
            <artifactId>mybatis-plus-join-boot-starter</artifactId>
            <version>1.4.7.2</version>
        </dependency>

继承

  • (必须)mapper继承MPJBaseMapper
public interface CarIllegalMapper extends MPJBaseMapper<CarIllegal>
{
}
  • (可选)service继承MPJBaseService
public interface ICarIllegalService  extends MPJBaseService<CarIllegal>{}
  • (可选)serviceImpl继承MPJBaseServiceImpl
@Service
public class CarIllegalServiceImpl extends MPJBaseServiceImpl<CarIllegalMapper, CarIllegal> implements ICarIllegalService
{}

开始使用

现有一张car_illegal(车辆违章)表和一张attachments_file(附件)表,其关联关系是每辆违章车数据可能对应着一条或多条的违章图片(附件),以这两张表为例来进行一对一和一对多测试。

一对一

说明

  • CarIllegalDto.class 查询结果返回类(resultType)
  • selectAll() 查询指定实体类的全部字段
  • select() 查询指定的字段,支持可变参数,同一个select只能查询相同表的字段
  • selectAs() 字段别名查询,用于数据库字段与业务实体类属性名不一致时使用

leftJoin() 参数说明

  • 第一个参数: 参与连表的实体类class
  • 第二个参数: 连表的ON字段,这个属性必须是第一个参数实体类的属性
  • 第三个参数: 参与连表的ON的另一个实体类属性

默认主表别名是t,其他的表别名以先后调用的顺序使用t1,t2,t3…

  • selectAssociation()一对一查询
  • selectCollection()一对多查询
@SpringBootTest(classes = DeXinApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@RunWith(SpringRunner.class)
@Slf4j
class DeXinApplicationTests {

    @Autowired
    private CarIllegalMapper carIllegalMapper;

    @Test
    public void testSelect() {
         MPJLambdaWrapper wrapper = new MPJLambdaWrapper<CarIllegalDto>()
                .selectAll(CarIllegalDto.class)
                .selectAssociation(AttachmentsFile.class,CarIllegalDto::getAttachmentsFile)
                   .leftJoin(AttachmentsFile.class,AttachmentsFile::getTargetId,CarIllegal::getId);
        List<CarIllegalDto> carIllegalDtoList = carIllegalMapper.selectJoinList(CarIllegalDto.class,wrapper);
    }
}

返回的实体类

@Data
public class  CarIllegalDto extends  CarIllegal
{
    AttachmentsFile attachmentsFile;

    List<AttachmentsFile> attachmentsFileList;
}

 查询结果

一对多

  @Test
    public void testSelect() {
        MPJLambdaWrapper wrapper = new MPJLambdaWrapper<CarIllegalDto>()
                .selectAll(CarIllegalDto.class)
                .selectCollection(AttachmentsFile.class,CarIllegalDto::getAttachmentsFileList)
                .leftJoin(AttachmentsFile.class,AttachmentsFile::getTargetId,CarIllegal::getId);
        List<CarIllegalDto> carIllegalDtoList = carIllegalMapper.selectJoinList(CarIllegalDto.class,wrapper);
        System.out.println(1);
    }

结果 

分页查询

连表分页查询返回所有命中记录(请启用mybatis-plus分页插件)

import com.baomidou.mybatisplus.core.metadata.IPage; 


   @Test
    public void testSelect() throws IOException {
        MPJLambdaWrapper wrapper = new MPJLambdaWrapper<CarIllegalDto>()
                .selectAll(CarIllegalDto.class)
                .selectAs(AttachmentsFile::getId,CarIllegalDto::getCarNo)
                .selectCollection(AttachmentsFile.class,CarIllegalDto::getAttachmentsFileList)
                .leftJoin(AttachmentsFile.class,AttachmentsFile::getTargetId, CarIllegal::getId);
        IPage<CarIllegalDto> carIllegalDtoList = carIllegalMapper.selectJoinPage(new Page<>(1, 10),CarIllegalDto.class,wrapper);
        System.out.println(carIllegalDtoList);
    }

结果

5、MPJLambdaWrapper所有方法说明

select

  • 查询指定字段 
select(AttachmentsFile::getName)
  • 支持可变参数
select(AttachmentsFile::getName,AttachmentsFile::getEnterpriseId)
  • 自定义字符串查询,需要对查询的表命名别名
select("file.id");
select("file.id as 'pid'");
select("file.id", "file.name");

//需要对表进行别名
 .leftJoin(AttachmentsFile.class,"file",AttachmentsFile::getTargetId,CarIllegal::getId);

selectAll

  • 查询指定类的全部字段 
.selectAll(CarIllegalDto.class)

注意事项:

  • 一般一次查询只建议调用一次selectAll(), 因为不同表之间可能会存在相同的字段, 比如id,create_time等通用字段, 多次调用会导致字段名重复, 除非能保证字段不重复
  • 所以一次查询推荐只使用一次, 并且通常是对主表使用, 其他表字段通过其他方式查询, 比如select, selectAs, selectAsClass等

selectAs

  • 别名查询 
.selectAs(AttachmentsFile::getId,CarIllegalDto::getCarNo)

//对应sql
t.id AS carNo

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java使用split截取字符串过程解析

    Java使用split截取字符串过程解析

    这篇文章主要介绍了Java使用split截取字符串过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • SpringCloud Config统一配置中心问题分析解决与客户端动态刷新实现

    SpringCloud Config统一配置中心问题分析解决与客户端动态刷新实现

    springcloud config是一个解决分布式系统的配置管理方案。它包含了 client和server两个部分,server端提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client端通过接口获取数据、并依据此数据初始化自己的应用
    2022-10-10
  • java stringbuffer的用法示例

    java stringbuffer的用法示例

    这篇文章主要介绍了java stringbuffer的用法示例,字符串缓冲区,是一个容器(当返回到的是String时而且长度不确定,数据类型不确定时就可以用StringBuffer)其实底层还是数组,只是被封装了,对外提供了方法,初始容量为16个字符
    2014-01-01
  • JAVA设计模式---原型模式你了解吗

    JAVA设计模式---原型模式你了解吗

    这篇文章主要介绍了JAVA 原型模式的的相关资料,文中讲解非常细致,实例帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2021-09-09
  • Java实现发送短信验证码功能

    Java实现发送短信验证码功能

    这篇文章主要为大家详细介绍了Java实现发送短信验证码功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • Java实现冒泡排序简单示例

    Java实现冒泡排序简单示例

    冒泡排序(Bubble Sort)是一种简单的排序算法,它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来,下面这篇文章主要给大家介绍了关于Java实现冒泡排序的相关资料,需要的朋友可以参考下
    2023-06-06
  • eclipse输出Hello World的实现方法

    eclipse输出Hello World的实现方法

    这篇文章主要介绍了eclipse输出Hello World的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • java GUI实现学生图书管理简单实例

    java GUI实现学生图书管理简单实例

    这篇文章主要为大家详细介绍了java GUI实现学生图书管理简单示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • 如何使用Java操作Zookeeper

    如何使用Java操作Zookeeper

    这篇文章主要介绍了如何使用Java操作Zookeeper,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下
    2021-04-04
  • Spring依赖注入DI之三种依赖注入类型详解

    Spring依赖注入DI之三种依赖注入类型详解

    这篇文章主要介绍了Spring依赖注入DI之三种依赖注入类型详解,通过 @Autowired 注解,字段注入的实现方式非常简单而直接,代码的可读性也很强,事实上,字段注入是三种注入方式中最常用、也是最容易使用的一种,需要的朋友可以参考下
    2023-09-09

最新评论