MyBatis-Plus實(shí)現(xiàn)跨表查詢并返回分頁(yè)
1. 概述
本文檔詳細(xì)介紹基于MyBatis-Plus框架實(shí)現(xiàn)的跨表查詢分頁(yè)功能。以供應(yīng)商物料查詢?yōu)槔故救绾瓮ㄟ^(guò)多表關(guān)聯(lián)查詢并返回標(biāo)準(zhǔn)分頁(yè)對(duì)象的技術(shù)實(shí)現(xiàn)方案。
2. 技術(shù)棧
ORM框架: MyBatis-Plus
數(shù)據(jù)庫(kù): MySQL(使用LIMIT進(jìn)行分頁(yè))
分頁(yè)組件: MyBatis-Plus Page對(duì)象
架構(gòu)模式: Repository + Mapper + XML三層架構(gòu)
3. 核心實(shí)現(xiàn)原理
3.1 分頁(yè)策略
采用手動(dòng)分頁(yè)方式,分為兩步執(zhí)行:
查詢總數(shù): 執(zhí)行COUNT查詢獲取符合條件的總記錄數(shù)
查詢數(shù)據(jù): 根據(jù)偏移量(offset)和頁(yè)大小(size)查詢具體數(shù)據(jù)
3.2 為什么選擇手動(dòng)分頁(yè)
跨表查詢涉及LEFT JOIN,MyBatis-Plus自動(dòng)分頁(yè)可能存在性能問(wèn)題
可以精確控制SQL語(yǔ)句,優(yōu)化查詢性能
支持復(fù)雜的動(dòng)態(tài)條件拼接
4. 代碼實(shí)現(xiàn)詳解
4.1 參數(shù)對(duì)象設(shè)計(jì)
SupplierIdParam.java - 查詢參數(shù)封裝
@Getter
@Setter
@ToString
public class SupplierIdParam extends PageQueryParam {
private Long tenantId; // 租戶ID
private Long supplierId; // 供應(yīng)商ID
private String materialCategoryExternalCode; // 物料分類外部編碼
private String materialCategoryName; // 物料分類名稱
private String materialName; // 物料名稱
private String materialExternalCode; // 物料編碼
private String materialStatus; // 物料狀態(tài)
private String pricingType; // 定價(jià)類型
// ... 其他字段
}
關(guān)鍵點(diǎn):
繼承PageQueryParam,包含currentPage和pageSize分頁(yè)參數(shù)
支持多維度動(dòng)態(tài)查詢條件
使用包裝類型,便于判斷參數(shù)是否為空
4.2 領(lǐng)域?qū)ο笤O(shè)計(jì)
SupplierMaterialDO.java - 供應(yīng)商物料實(shí)體
@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;
// ... 其他字段
}
關(guān)鍵點(diǎn):
- 使用@TableName指定表名
- autoResultMap = true支持復(fù)雜結(jié)果映射
- 實(shí)現(xiàn)BaseEntity接口,包含通用字段
4.3 Repository層實(shí)現(xiàn)
SupplierMaterialRepository.java
@Repository
public class SupplierMaterialRepository extends HussarServiceImpl<SupplierMaterialMapper, SupplierMaterialDO> {
@Resource
private SupplierMaterialMapper supplierMaterialMapper;
public Page<SupplierMaterialDO> queryMaterialsBySupplierId(SupplierIdParam param) {
Long tenantId = param.getTenantId();
// 第一步:查詢總數(shù)
Long total = supplierMaterialMapper.queryMaterialsBySupplierIdCount(param, tenantId);
// 第二步:創(chuàng)建分頁(yè)對(duì)象
Page<SupplierMaterialDO> page = new Page<>(param.getCurrentPage(), param.getPageSize(), total);
// 第三步:查詢分頁(yè)數(shù)據(jù)
List<SupplierMaterialDO> supplierMaterialDOList =
supplierMaterialMapper.queryMaterialsBySupplierId(param, tenantId, page.offset(), page.getSize());
// 第四步:設(shè)置結(jié)果集
if (CollectionUtils.isNotEmpty(supplierMaterialDOList)) {
page.setRecords(supplierMaterialDOList);
}
return page;
}
}實(shí)現(xiàn)要點(diǎn):
- 分離計(jì)數(shù)查詢: 單獨(dú)執(zhí)行COUNT查詢,避免查詢不必要的數(shù)據(jù)列
- 計(jì)算偏移量: 使用page.offset()方法自動(dòng)計(jì)算OFFSET值
- 空值保護(hù): 檢查查詢結(jié)果是否為空,避免設(shè)置null集合
- 租戶隔離: 所有查詢都攜帶tenantId,實(shí)現(xiàn)多租戶數(shù)據(jù)隔離
4.4 Mapper接口定義
SupplierMaterialMapper.java
@Mapper
public interface SupplierMaterialMapper extends BaseMapper<SupplierMaterialDO>, HussarMapper<SupplierMaterialDO> {
/**
* 查詢總數(shù)
*/
Long queryMaterialsBySupplierIdCount(@Param("param") SupplierIdParam param,
@Param("tenantId") Long tenantId);
/**
* 查詢分頁(yè)數(shù)據(jù)
*/
List<SupplierMaterialDO> queryMaterialsBySupplierId(@Param("param") SupplierIdParam param,
@Param("tenantId") Long tenantId,
@Param("offset") Long offset,
@Param("size") Long size);
}
設(shè)計(jì)說(shuō)明:
- 使用@Param注解明確參數(shù)名稱,便于XML中引用
- 將offset和size作為獨(dú)立參數(shù)傳遞,提高SQL可讀性
- 返回類型分別為L(zhǎng)ong和List<SupplierMaterialDO>
4.5 MyBatis XML實(shí)現(xiàn)
SupplierMaterialMapper.xml
總數(shù)查詢SQL
<select id="queryMaterialsBySupplierIdCount" resultType="java.lang.Long">
SELECT count(*) AS total
FROM t_supplier_material tsm
LEFT JOIN t_material tm ON tsm.material_id = tm.id
WHERE tsm.delete_flag = '0'
AND tsm.tenant_id = #{tenantId}
<if test="param.supplierId != null and param.supplierId != ''">
AND supplier_id = #{param.supplierId}
</if>
<if test="param.materialCategoryExternalCode != null and param.materialCategoryExternalCode != ''">
AND tsm.material_category_external_code LIKE CONCAT('%', #{param.materialCategoryExternalCode}, '%')
</if>
<if test="param.materialCategoryName != null and param.materialCategoryName != ''">
AND tsm.material_category_name LIKE CONCAT('%', #{param.materialCategoryName}, '%')
</if>
<if test="param.materialName != null and param.materialName != ''">
AND tsm.name LIKE CONCAT('%', #{param.materialName}, '%')
</if>
<if test="param.materialExternalCode != null and param.materialExternalCode != ''">
AND tsm.external_code LIKE CONCAT('%', #{param.materialExternalCode}, '%')
</if>
<if test="param.materialStatus != null and param.materialStatus != ''">
AND tm.status = #{param.materialStatus}
</if>
<if test="param.pricingType != null and param.pricingType != ''">
AND tm.pricing_type = #{param.pricingType}
</if>
</select>分頁(yè)數(shù)據(jù)查詢SQL
<select id="queryMaterialsBySupplierId"
resultType="com.mdgyl.hussar.basic.supplier.masterdata.domain.SupplierMaterialDO">
SELECT tsm.*
FROM t_supplier_material tsm
LEFT JOIN t_material tm ON tsm.material_id = tm.id
WHERE tsm.delete_flag = '0'
AND tsm.tenant_id = #{tenantId}
<!-- 動(dòng)態(tài)條件與COUNT查詢保持一致 -->
<if test="param.supplierId != null and param.supplierId != ''">
AND supplier_id = #{param.supplierId}
</if>
<if test="param.materialCategoryExternalCode != null and param.materialCategoryExternalCode != ''">
AND tsm.material_category_external_code LIKE CONCAT('%', #{param.materialCategoryExternalCode}, '%')
</if>
<!-- ... 其他動(dòng)態(tài)條件 ... -->
ORDER BY tsm.id DESC
LIMIT #{offset}, #{size}
</select>SQL編寫(xiě)要點(diǎn):
- 表別名規(guī)范: 使用簡(jiǎn)短且有意義的別名(如tsm、tm)
- 動(dòng)態(tài)條件: 使用<if>標(biāo)簽實(shí)現(xiàn)條件可選,確保COUNT和DATA查詢條件一致
- 模糊查詢: 使用CONCAT('%', value, '%')實(shí)現(xiàn)LIKE模糊匹配
- 軟刪除過(guò)濾: 始終添加delete_flag = '0'條件
- 排序規(guī)則: 使用ORDER BY id DESC保證數(shù)據(jù)穩(wěn)定性
- LIMIT分頁(yè): 使用LIMIT #{offset}, #{size}實(shí)現(xiàn)物理分頁(yè)
到此這篇關(guān)于MyBatis-Plus實(shí)現(xiàn)跨表查詢并返回分頁(yè)的文章就介紹到這了,更多相關(guān)MyBatis-Plus跨表查詢分頁(yè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MyBatis-Plus實(shí)現(xiàn)分頁(yè)查詢兩種方案詳解
- MybatisPlus實(shí)現(xiàn)多表的關(guān)聯(lián)查詢,實(shí)現(xiàn)分頁(yè),多條件查詢?nèi)^(guò)程
- Spring3整合MyBatis實(shí)現(xiàn)分頁(yè)查詢和搜索功能
- mybatisPlus實(shí)現(xiàn)多表連接分頁(yè)動(dòng)態(tài)查詢方式
- MybatisPlus一對(duì)多聯(lián)表查詢及分頁(yè)的解決過(guò)程
- 在MyBatis中進(jìn)行分頁(yè)查詢的兩種方法詳解
- MyBatis分頁(yè)查詢實(shí)戰(zhàn)案例完整流程
- MyBatis-Plus進(jìn)行分頁(yè)查詢優(yōu)化的實(shí)踐指南
相關(guān)文章
解決idea配置Tomcat Deployment沒(méi)有artifact選項(xiàng)的問(wèn)題
今天在配置的時(shí)候tomcat deployment中卻找不到artifact,沒(méi)有artifact就不能打成war包上傳到服務(wù)器了,那么怎么解決沒(méi)有artifact選項(xiàng)的問(wèn)題呢,今天通過(guò)本文給大家分享idea配置Tomcat Deployment沒(méi)有artifact選項(xiàng)的解決方案,一起看看吧2023-10-10
Java http請(qǐng)求封裝工具類代碼實(shí)例
這篇文章主要介紹了Java http請(qǐng)求封裝工具類代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
200行Java代碼編寫(xiě)一個(gè)計(jì)算器程序
本篇文章給大家分享的只用200行java代碼,實(shí)現(xiàn)一個(gè)計(jì)算器程序,不僅能夠計(jì)算加減乘除,還能夠匹配小括號(hào)。實(shí)現(xiàn)代碼超簡(jiǎn)單,需要的朋友參考下吧2017-12-12
Java+Selenium實(shí)現(xiàn)控制瀏覽器的啟動(dòng)選項(xiàng)Options
這篇文章主要為大家詳細(xì)介紹了如何使用java代碼利用selenium控制瀏覽器的啟動(dòng)選項(xiàng)Options的代碼操作,文中的示例代碼講解詳細(xì),感興趣的可以了解一下2023-01-01
Java基于代理模式解決紅酒經(jīng)銷問(wèn)題詳解
這篇文章主要介紹了Java基于代理模式解決紅酒經(jīng)銷問(wèn)題,詳細(xì)描述了代理模式的概念、原理并結(jié)合實(shí)例形式分析了java基于代理模式解決紅酒經(jīng)銷問(wèn)題的相關(guān)步驟、實(shí)現(xiàn)方法與操作注意事項(xiàng),需要的朋友可以參考下2018-04-04
IntelliJ IDEA修改新建文件自動(dòng)生成注釋的user名
今天小編就為大家分享一篇關(guān)于IntelliJ IDEA修改新建文件自動(dòng)生成注釋的user名,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10
Java一維數(shù)組和二維數(shù)組元素默認(rèn)初始化值的判斷方式
這篇文章主要介紹了Java一維數(shù)組和二維數(shù)組元素默認(rèn)初始化值的判斷方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08

