1. 概述

在数据库开发中,跨表查询和分页返回是最常见的需求之一。这篇文章就专门聊聊如何基于MyBatis-Plus框架,实现一个靠谱的跨表查询分页功能。我们会以供应商物料的实际查询场景为例,一步步拆解多表关联查询,并最终拿到一个标准的分页对象。

MyBatis-Plus实现跨表查询并返回分页

2. 技术栈

先简单交代一下我们用到的技术组件:

3. 核心实现原理

3.1 分页策略

这里不搞什么玄乎的自动分页,我们走的是手动控制路线。整个过程分两步:

3.2 为什么选择手动分页

你可能要问了,MyBatis-Plus不是自带分页插件吗?为啥还自己动手?原因其实很简单:

4. 代码实现详解

4.1 参数对象设计

首先,我们需要一个参数对象来承载查询条件。它继承了PageQueryParam,这样就有了currentPagepageSize这两个核心分页参数。

@Getter
@Setter
@ToString
public class SupplierIdParam extends PageQueryParam {
    private Long tenantId;                        // 租户ID
    private Long supplierId;                      // 供应商ID
    private String materialCategoryExternalCode;  // 物料分类外部编码
    private String materialCategoryName;          // 物料分类名称
    private String materialName;                  // 物料名称
    private String materialExternalCode;          // 物料编码
    private String materialStatus;                // 物料状态
    private String pricingType;                   // 定价类型
    // ... 其他字段
}

设计这个对象时,有几点值得留意:

4.2 领域对象设计

接着是承载数据的实体,它映射到数据库的t_supplier_material表:

@Getter
@Setter
@TableName(value = "t_supplier_material", autoResultMap = true)
public class SupplierMaterialDO implements BaseEntity {
    private Long id;
    private Long tenantId;
    private Long supplierDataId;
    private Long materialCategoryId;
    private String materialCategoryExternalCode;
    private String materialCategoryName;
    private Long materialId;
    private String externalCode;
    private String name;
    // ... 其他字段
}

这里有两个细节:

4.3 Repository层实现

到了组织查询逻辑的环节,看SupplierMaterialRepository

@Repository
public class SupplierMaterialRepository extends HussarServiceImpl {
    @Resource
    private SupplierMaterialMapper supplierMaterialMapper;
    public Page queryMaterialsBySupplierId(SupplierIdParam param) {
        Long tenantId = param.getTenantId();
        // 第一步:查询总数
        Long total = supplierMaterialMapper.queryMaterialsBySupplierIdCount(param, tenantId);
        // 第二步:创建分页对象
        Page page = new Page<>(param.getCurrentPage(), param.getPageSize(), total);
        // 第三步:查询分页数据
        List supplierMaterialDOList = 
            supplierMaterialMapper.queryMaterialsBySupplierId(param, tenantId, page.offset(), page.getSize());
        // 第四步:设置结果集
        if (CollectionUtils.isNotEmpty(supplierMaterialDOList)) {
            page.setRecords(supplierMaterialDOList);
        }
        return page;
    }
}

实现要点其实很清晰:

4.4 Mapper接口定义

数据访问层接口,定义了两个核心方法:

@Mapper
public interface SupplierMaterialMapper extends BaseMapper, HussarMapper {
    
    /**
     * 查询总数
     */
    Long queryMaterialsBySupplierIdCount(@Param("param") SupplierIdParam param, 
                                         @Param("tenantId") Long tenantId);
    
    /**
     * 查询分页数据
     */
    List queryMaterialsBySupplierId(@Param("param") SupplierIdParam param, 
                                                        @Param("tenantId") Long tenantId, 
                                                        @Param("offset") Long offset, 
                                                        @Param("size") Long size);
}

设计上,有几点值得注意:

4.5 MyBatis XML实现

SQL部分,我们先看总数查询:

再看分页数据查询:

SQL编写上有几个关键点:

本文转载于:https://www.jb51.net/program/3628827ub.htm 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。