Mybatis 多表之间的分页查询
分页查询
-
什么是分页?
分页,是一种将所有数据分段展示给用户的技术。用户每次看到的不是全部数据,而是其中的一部分,如果在其中没有找到自习自己想要的内容,用户可以通过制定页码或是翻页的方式转换可见内容,直到找到自己想要的内容为止。其实这和我们阅读书籍很类似。 -
分页的意义
(1). 数据方面的原因,减少数据库压力
(2). 增强用户使用体验需要
场景
今天早上同事在和前端对接得时候出现了一点分歧原因是因为页面上有一个布局上需要进行分页,但是后端接口返回的数据中没有allPage、allCount两个参数导致前端没法分页。后端同事说无法分页是由于他的后端查询sql是一个复杂sql,没办法用常规的分页来做。
但其实mybatis是是支持多表复杂sql的分页的,告知同事后以将该问题解决。同时在此记录网上有遇到相同问题的小伙伴可以参考借鉴。
解决办法
利用mybatis的PageResult可以处理这个问题,PageResult根据使用使用者的req中的pageIndex、pageSize封装进mybatis自定的Page对象作为参数传入就能对查询的结果自动分页。
PageResult:
public class PageResult<T> implements Serializable {
private long allCount;
private long allPages;
private long pageNum;
private long pageSize;
private List<T> dataItems;
public <R> PageResult<R> convert(Function<? super T, ? extends R> mapper) {
List<R> collect = (List)this.dataItems.stream().map(mapper).collect(Collectors.toList());
PageResult<R> result = new PageResult();
result.setAllCount(this.getAllCount());
result.setAllPages(this.allPages);
result.setPageNum(this.pageNum);
result.setPageSize(this.pageSize);
result.setDataItems(collect);
return result;
}
......
}
如何使用
只要我们在自定义复杂sql的时候灵活运用,多表分页查询也能达到很好的效果:
- 自定义Mapper的返回值接收用PageResult
- 查询条件必须带Page参数
DEMO
mapper.java写法:
/**
* 分页查询
* @param configReq 条件入参
* @param page 分页参数 : 必传,里面是pageIndex和pageSize
* @param frequency 查询条件
* @return 分页后的结果
*/
PageResult<ConfigBo> listConfig(@Param("configReq") ConfigReq configReq, Page page,@Param("frequency") Integer frequency);
mapper.xml写法:
<select id="listConfig" parameterType="com.hikcreate.hdsp.service.supervise.infra.model.request.ConfigReq"
resultType="com.hikcreate.hdsp.service.supervise.infra.model.bo.ConfigBo">
select
config.id AS configId,
config.supervise_name AS superviseName,
type.type_name AS typeName,
rel.model_id AS modelId,
config.enable_state AS enableState,
type.type_code AS typeCode
from supervise_config config
left join supervise_business_type type on config.business_type_code = type.type_code
left join supervise_model_dept_rel rel on config.id = rel.supervise_config_id
left join supervise_rule_config rule on config.id = rule.supervise_config_id where 1 = 1
<if test="configReq.superviseName != null and configReq.superviseName != ''" >
and config.supervise_name = #{configReq.superviseName}
</if>
<if test="configReq.typeCode != null and configReq.typeCode != ''" >
and type.type_code = #{configReq.typeCode}
</if>
<if test="frequency != null " >
and rule.frequency = #{frequency}
</if>
</select>
mapper.java注意入参需要有Page page这个参数,接收返回值时需要用PageResult进行接收,mapper.xml中的写法就和正常写法一致,因为PageResult在封装返回值时候会自动将分页查询结果的参数封装进返回结果之中
效果
总结
只要思想不滑坡,困难总比办法多。