【MyBatis】PageHelper无法处理多对多查询分页问题

前言

最近在使用PageHelper时,发现其无法正常对多对多查询出的结果集进行正确分页。原因其实在PageHelper官网写着了:
在这里插入图片描述
那么解决该问题便会变得非常棘手,笔者选择的是用MyBatis的方式手动进行分页操作,正好也复习巩固一下SQL语句和多对多映射操作。

一、子查询分页

利用子查询分页可以在SQL层面上解决分页问题,剩下的都交给配置结果集映射(resultMap)来做。

该思路是网上一篇大神的博客提供的:MyBatis一对多或多对多分页查询的结果条数不符合预期的问题解决

使用子查询分页有以下几点需要注意:

		SELECT
            b.id,b.title,t.id tid,t.name tname
        FROM
            (SELECT t_blog.`id`,t_blog.title FROM t_blog ORDER BY t_blog.id DESC LIMIT 0,5) b
        INNER JOIN
            blog_type bt
        ON
            b.`id`=bt.`bid`
        INNER JOIN
            t_type t
        ON
            bt.`tid`=t.`id`
  1. 这条SQL语句的第四行 :
(SELECT t_blog.`id`,t_blog.title FROM t_blog ORDER BY t_blog.id DESC LIMIT 0,5) b

意思就是将t_blog表的字段先分页查出来,然后将其分页后的结果看作是一个新的表,并将该新表取别名叫b。(order by t_blog.id DESC是按照id降序排列,也是个小细节)

  1. 既然如此,那剩下的查询语句都以b表为基准,进行内联,多表操作,实现了分页多对多查询
  2. 查询结果:

在这里插入图片描述这里可以看到,分页的期望是5条数据(LIMIT 0,5),这里却查出来8个数据。但是别忘了,这是多对多查询,还关联了t_type表,最终进行完结果集映射,这8条数据就会变成5条。

二、编写对应的mapper

  1. 接口
List<BlogQuery> queryAllBlogByLimit(Map<String,Integer> map);
  1. 实体类:
public class BlogQuery {

    private int id;
    private String title;
    private Date updateTime;
    private Boolean recommend;
    private Boolean published;
    private int typeId;
    private List<Type> types;
}

public class Type {

    private int id;
    private String name;
    private List<Blog> blogs;   //该Type类型下的所有博客
}
  1. 对应的mapper
<select id="queryAllBlogByLimit" parameterType="map" resultMap="blogquery">
        SELECT
            b.id,b.title,b.update_time,b.recommend,b.published,t.id tid,t.name tname
        FROM
            (SELECT t_blog.`id`,t_blog.title,t_blog.update_time,t_blog.recommend,t_blog.published FROM t_blog ORDER BY t_blog.id DESC LIMIT #{startIndex},#{pageSize}) b
        INNER JOIN
            blog_type bt
        ON
            b.`id`=bt.`bid`
        INNER JOIN
            t_type t
        ON
            bt.`tid`=t.`id`
    </select>
    
	<resultMap id="blogquery" type="com.lubenwei.vo.BlogQuery">
        <id property="id" column="id"/>
        <result property="title" column="title"/>
        <result property="updateTime" column="update_time"/>
        <result property="recommend" column="recommend"/>
        <result property="published" column="published"/>
        <!--如果属性是一个Java类的话,就需要配置association; 如果属性是一个集合, 那就需要配置collection-->
        <collection property="types" ofType="Type">
            <result property="id" column="tid" />
            <result property="name" column="tname" />
        </collection>
    </resultMap>

到这里MyBatis能做的部分就做完了,前端只需要给我们提供一个Map,里面存放着分页的起始位置(startIndex)和页码容量(pageSize),数据库就会返回想要的分页结果。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值