多表查询分页[多次查询]

问题描述:

1:我们使用PageHelper插件的时候,PageHelper.startPage(pageNow,pageSize)要放在查询语句的前面

2:当startPage的后面有多次查询的话,它只对第一条查询语句有效果

3:假如要进行多次查询,然后对结果进行分页,关注点是:对最后的结果进行分页,而不是第一次查询出来的结果

最终解决办法有2种:第一种:依旧是用老套路,用原始自己写的PageUtil做【因为里面存放的数据就是List的,所以将最终查询的结果(不管你查询多少次)直接放进去即可】

           第二种:重新写一个SQL语句,解决问题所需【这样就只需查询一次】

效果如下:

开始代码如下:

    @Override //重写父类的无条件分页查询
    public PageUtil queryAllByPage(int pageNow, int pageSize) {
        //先定义一个存放查询结果的地方
        List<SpecsParamVO> specsParam = new ArrayList<>();
        //先实例化一个Example对象
        TbSpuExample example = new TbSpuExample();
        //设置分页的数据
        PageHelper.startPage(pageNow,pageSize);
        //无条件查询tb_spu表中的所有数据
        List<TbSpu> tbSpus = spuMapper.selectByExample(example);
        log.info("共查询到:"+tbSpus.size()+"条数据");
        //遍历每一条数据的id
        for (TbSpu spu:tbSpus){
            //根据id查询tb_sku表,每个id对应多少条数据
            TbSkuExample skuExample = new TbSkuExample();
            //利用skuExample进行条件查询
            TbSkuExample.Criteria criteria = skuExample.createCriteria();
            //in条件查询
            //涉及:long类型转integer类型:
            //criteria.andSpuIdEqualTo(Integer.valueOf(spu.getId()+""));
            criteria.andSpuIdEqualTo(Integer.valueOf(spu.getId().toString()));
            //开始查询
            List<TbSku> tbSkus = skuMapper.selectByExample(skuExample);
            //对应的条数就是规格数量
            long specsCount = tbSkus.size();
            log.info("id为:"+spu.getId()+"查询到的规格数量一共是:"+specsCount);
            //根据id查询tb_spu_detail表,统计参数数量
            TbSpuDetail detail = spuDetailMapper.selectByPrimaryKey(spu.getId());
            //获取detail的specifications,即所有的参数
            try {
                String[] split = detail.getSpecifications().split("group");
                //对应的数量就是参数数量
                long paramCount = split.length-1;
                log.info("id为:"+spu.getId()+"查询到的参数数量一共是:"+paramCount);
                //存放每条数据
                SpecsParamVO vo = new SpecsParamVO(spu.getId(), spu.getTitle(), paramCount, specsCount);
                specsParam.add(vo);
            }catch (Exception e){
                log.info("该条数据字符串切分异常:"+spu.getId());
                //存放每条数据
                SpecsParamVO vo = new SpecsParamVO(spu.getId(), spu.getTitle(), (long)0, specsCount);
            }
        }

        //使用pageInfo对结果进行封装
        PageInfo<SpecsParamVO> pageInfo = new PageInfo<>(specsParam);
        log.info(pageInfo.getTotal());  //始终是15条数据
        log.info(pageInfo.getPages());  //总页数也是只有1条
        return pageInfo;
    }

解决方法一:

1.重新编写一个工具类PageUtil[粘贴即可用]

package com.blb.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class PageUtil {
    /**
     * 总记录数
     */
    private int totalCount;
    /**
     * 每页的条数
     */
    private int pageSize;
    /**
     * 总页数
     */
    private int totalPage;
    /**
     * 当前是第几页
     */
    private int pageNow;
    /**
     * 当前页的数据
     */
    private List data;
    /**
     * 当前页的下一页是几
     */
    private int next;
    /**
     * 当前页的上一页是几
     */
    private int last;
    /**
     * 是否有下一页
     */
    private boolean hasNext;
    /**
     * 是否有上一页
     */
    private boolean hasLast;
    /**
     * 是否是第一页
     */
    private boolean isFirst;
    /**
     * 是否是最后一页
     */
    private boolean isLast;

    /**
     * 自定义的页码的格式
     */
    private int num = 7;
    /**
     * 页码数
     */
    private List pages = new ArrayList<>();

    // 用于循环的第一个
    private int forMin;

    // 用于循环的最后一个
    private int forMax;

    private String buidUrl;

    /**
     * 分页时携带的查询条件
     */
    private Map param;

    public String getBuidUrl() {
        StringBuffer url = new StringBuffer();
        if (null != param && param.size() > 0) {
            Set<Map.Entry<String, String>> entrySet = param.entrySet();
            for (Map.Entry<String, String> e : entrySet) {
                url.append("&param." + e.getKey() + "=" + e.getValue());
            }
        }
        return url.toString();
    }

    public PageUtil(int totalCount, int pageNow, int pageSize, Map param) {
        this.totalCount = totalCount;
        this.pageSize = pageSize;
        this.pageNow = pageNow;
        this.param = param;
        // 先把总页数算出来
        this.totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : (totalCount / pageSize) + 1;
        this.next = pageNow + 1;
        this.last = pageNow - 1;
        if (this.totalPage == 1) {
            this.isFirst = true;
            this.isLast = true;
            this.hasLast = false;
            this.hasNext = false;
        } else {
            if (this.pageNow <= 1) {
                this.pageNow = 1;
                this.last = 1;
                this.isFirst = true;
                this.hasLast = false;
                this.hasNext = true;
                this.isLast = false;
            } else if (this.pageNow >= this.totalPage) {
                this.pageNow = this.totalPage;
                this.next = this.totalPage;
                this.isFirst = false;
                this.isLast = true;
                this.hasLast = true;
                this.hasNext = false;
            } else {
                this.isFirst = false;
                this.isLast = false;
                this.hasLast = true;
                this.hasNext = true;
            }
        }
        // 设置最大值和最小值
        int min = (int) (this.pageNow - Math.floor(num / 2));
        int max = (int) (this.pageNow + Math.floor(num / 2));
        if (totalPage >= num) {
            if (min < 1) {
                forMin = 1;
                forMax = num;
                for (int i = forMin; i <= forMax; i++) {
                    pages.add(i);
                }
                return;
            }
            if (max > totalPage) {
                forMax = totalPage;
                forMin = totalPage - num + 1;
                for (int i = forMin; i <= forMax; i++) {
                    pages.add(i);
                }
                return;
            }
            for (int i = min; i <= max; i++) {
                pages.add(i);
            }
        } else {
            for (int i = 1; i <= totalPage; i++) {
                pages.add(i);
            }
        }
    }

    public int getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }

    public int getPageNow() {
        return pageNow;
    }

    public void setPageNow(int pageNow) {
        this.pageNow = pageNow;
    }

    public List getData() {
        return data;
    }

    public void setData(List data) {
        this.data = data;
    }

    public int getNext() {
        return next;
    }

    public void setNext(int next) {
        this.next = next;
    }

    public int getLast() {
        return last;
    }

    public void setLast(int last) {
        this.last = last;
    }

    public boolean getHasNext() {
        return hasNext;
    }

    public void setHasNext(boolean hasNext) {
        this.hasNext = hasNext;
    }

    public boolean getHasLast() {
        return hasLast;
    }

    public void setHasLast(boolean hasLast) {
        this.hasLast = hasLast;
    }

    public boolean getIsFirst() {
        return isFirst;
    }

    public void setFirst(boolean isFirst) {
        this.isFirst = isFirst;
    }

    public boolean getIsLast() {
        return isLast;
    }

    public void setLast(boolean isLast) {
        this.isLast = isLast;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public List getPages() {
        return pages;
    }

    public void setPages(List pages) {
        this.pages = pages;
    }

    public Map getParam() {
        return param;
    }

    public void setParam(Map param) {
        this.param = param;
    }

}

2.service的代码修改

    @Override //重写父类的无条件分页查询
    public PageUtil queryAllByPage(int pageNow, int pageSize) {
        //先定义一个存放查询结果的地方
        List<SpecsParamVO> specsParam = new ArrayList<>();
        //先实例化一个Example对象
        TbSpuExample example = new TbSpuExample();
        //设置分页的数据
        PageHelper.startPage(pageNow,pageSize);
        //无条件查询tb_spu表中的所有数据
        List<TbSpu> tbSpus = spuMapper.selectByExample(example);
        log.info("共查询到:"+tbSpus.size()+"条数据");
        //遍历每一条数据的id
        for (TbSpu spu:tbSpus){
            //根据id查询tb_sku表,每个id对应多少条数据
            TbSkuExample skuExample = new TbSkuExample();
            //利用skuExample进行条件查询
            TbSkuExample.Criteria criteria = skuExample.createCriteria();
            //in条件查询
            //涉及:long类型转integer类型:
            //criteria.andSpuIdEqualTo(Integer.valueOf(spu.getId()+""));
            criteria.andSpuIdEqualTo(Integer.valueOf(spu.getId().toString()));
            //开始查询
            List<TbSku> tbSkus = skuMapper.selectByExample(skuExample);
            //对应的条数就是规格数量
            long specsCount = tbSkus.size();
            log.info("id为:"+spu.getId()+"查询到的规格数量一共是:"+specsCount);
            //根据id查询tb_spu_detail表,统计参数数量
            TbSpuDetail detail = spuDetailMapper.selectByPrimaryKey(spu.getId());
            //获取detail的specifications,即所有的参数
            try {
                String[] split = detail.getSpecifications().split("group");
                //对应的数量就是参数数量
                long paramCount = split.length-1;
                log.info("id为:"+spu.getId()+"查询到的参数数量一共是:"+paramCount);
                //存放每条数据
                SpecsParamVO vo = new SpecsParamVO(spu.getId(), spu.getTitle(), paramCount, specsCount);
                specsParam.add(vo);
            }catch (Exception e){
                log.info("该条数据字符串切分异常:"+spu.getId());
                //存放每条数据
                SpecsParamVO vo = new SpecsParamVO(spu.getId(), spu.getTitle(), (long)0, specsCount);
            }
        }      
        PageUtil pageUtil = new PageUtil((int) spuMapper.countByExample(example), pageNow, pageSize, null);
        pageUtil.setData(specsParam);
        return pageUtil;
    }

3.jsp页面分页代码

<!--分页-->
<div id="u1950-${pageUtil.data.size()+1}" class="preeval" style="width: 1100px; height: 49px;">
  <div id="u1961_div" class="ax_default _表格 u1951" style="visibility: inherit">
  <div class="pages">
      <ul>
        <li>
          <span>共</span><span style="color:#FF3C2C;">${pageUtil.totalPage}</span><span>页/</span><span style="color:#FF0000;">${pageUtil.totalCount}</span><span>条数据</span>
        </li>
        <c:if test="${!pageUtil.isFirst}">
          <li>
            <a href="${pageContext.request.contextPath}/specsParam/1/15">首页</a>
          </li>
        </c:if>
        <c:if test="${pageUtil.hasLast}">
          <li>
            <a href="${pageContext.request.contextPath}/specsParam/${pageUtil.last}/15">上一页</a>
          </li>
        </c:if>
        <c:forEach items="${pageUtil.pages}" var="page">
          <c:if test="${pageUtil.pageNow eq page}">
            <li>
              <a id="curr" href="${pageContext.request.contextPath}/specsParam/${page}/15">${page}</a>
            </li>
          </c:if>
          <c:if test="${pageUtil.pageNow ne page}">
            <li>
              <a href="${pageContext.request.contextPath}/specsParam/${page}/15">${page}</a>
            </li>
          </c:if>
        </c:forEach>
        <c:if test="${pageUtil.hasNext}">
          <li>
            <a href="${pageContext.request.contextPath}/specsParam/${pageUtil.next}/15">下一页</a>
          </li>
        </c:if>
        <c:if test="${!pageUtil.isLast}">
          <li>
            <a href="${pageContext.request.contextPath}/specsParam/${pageUtil.totalPage}/15">尾页</a>
          </li>
        </c:if>
      </ul>
  </div>
  </div>
</div>
</div>

解决办法二:

第一种办法显得太low了,所以我们通过写一个SQL语句解决问题,只用查询一次,也就不用自己写工具类了

1.写一个数据类用于存放最后查询出来的结果

package com.blb.vo;

import lombok.Data;

@Data
public class SpecsParamVO {
    private Long id;
    private String title;
    private Long specsCount;
    private String paramCount;

    public SpecsParamVO(Long id, String title, Long specsCount, String paramCount) {
        this.id = id;
        this.title = title;
        this.specsCount = specsCount;
        this.paramCount = paramCount;
    }

    public SpecsParamVO() {

    }
}

2.在mapper.xml中添加SQL语句

还有在对应的mapper接口添加该方法:

List<SpecsParamVO> getAll_SpecsParam();

<select id="getAll_SpecsParam" resultType="com.blb.vo.SpecsParamVO">
  select s.id, s.title,specifications as paramCount,count(s.id) as specsCount from
  (select * from tb_spu spu left join tb_spu_detail detail on spu.id = detail.spu_id) s
  left join tb_sku sku on s.id = sku.spu_id
  group by s.id
</select>

3.写service层的代码

特别注意:要注意对结果进行封装的位置

  【你是先查询,然后对结果进行字符串切分等操作,做完之后再进行封装】 --> 该做法会出问题,导致PageHelper分页不了

  【你是先查询,然后将结果进行封装,封装完之后将需要做字符串切分等操作取出来,做完操作之后重新设置回去(setList)】--> 完美解决问题

    @Override //通过SQL语句解决多次查询的问题
    public PageInfo queryAllByPage2(int pageNow, int pageSize) {
        //定义一个List集合,存放查询出来的数据
        ArrayList<SpecsParamVO> info = new ArrayList<>();
        //设置分页的数据
        PageHelper.startPage(pageNow,pageSize);
        //只需查询一次即可
        List<SpecsParamVO> list = spuMapper.getAll_SpecsParam();     //需要特别注意对查询结果封装的位置
        PageInfo<SpecsParamVO> infos = new PageInfo<>(list); //特别注意......
        log.info(infos.getTotal());
        log.info(infos.getPages());
        //遍历查询出来的数据--为了获取所有参数值
        for (SpecsParamVO sp : infos.getList()){
            String specifications = sp.getParamCount();
            //对字符串做切分操作
            try {
                String[] split = specifications.split("group");
                //对应的数量就是参数数量
                long paramCount = split.length-1;
                log.info("id为:"+sp.getId()+"查询到的参数数量一共是:"+paramCount);
                //存放每条数据
                SpecsParamVO vo = new SpecsParamVO(sp.getId(), sp.getTitle(), sp.getSpecsCount(), paramCount+"");
                info.add(vo);
            }catch (Exception e){
                log.info("该条数据字符串切分异常:"+sp.getId());
                //存放每条数据
                SpecsParamVO vo = new SpecsParamVO(sp.getId(), sp.getTitle(), sp.getSpecsCount(), "0");
                info.add(vo);
            }
        }
        infos.setList(info);     错误做法: 
//        //对结果进行封装
//        PageInfo<SpecsParamVO> pageInfo = new PageInfo<>(info);
//        log.info(pageInfo.getTotal());
//        log.info(pageInfo.getPages());
        return infos;
    }

4.jsp页面分页代码

<!--分页-->
<div id="u1950-${pageInfo.list.size()+1}" class="preeval" style="width: 1100px; height: 49px;">
  <div id="u1961_div" class="ax_default _表格 u1951" style="visibility: inherit">
    <div class="pages">
      <ul>
        <li>
          <span>共</span><span style="color:#FF3C2C;">${pageInfo.pages}</span><span>页/</span><span style="color:#FF0000;">${pageInfo.total}</span><span>条数据</span>
        </li>
        <c:if test="${!pageInfo.isFirstPage}">
          <li>
            <a href="${pageContext.request.contextPath}/specsParam/1/15">首页</a>
          </li>
        </c:if>
        <c:if test="${pageInfo.hasPreviousPage}">
          <li>
            <a href="${pageContext.request.contextPath}/specsParam/${pageInfo.lastPage}/15">上一页</a>
          </li>
        </c:if>
        <c:forEach items="${pageInfo.navigatepageNums}" var="page">
          <c:if test="${pageInfo.pageNum eq page}">
            <li>
              <a id="curr" href="${pageContext.request.contextPath}/specsParam/${page}/15">${page}</a>
            </li>
          </c:if>
          <c:if test="${pageInfo.pageNum ne page}">
            <li>
              <a href="${pageContext.request.contextPath}/specsParam/${page}/15">${page}</a>
            </li>
          </c:if>
        </c:forEach>
        <c:if test="${pageInfo.hasNextPage}">
          <li>
            <a href="${pageContext.request.contextPath}/specsParam/${pageInfo.nextPage}/15">下一页</a>
          </li>
        </c:if>
        <c:if test="${!pageInfo.isLastPage}">
          <li>
            <a href="${pageContext.request.contextPath}/specsParam/${pageInfo.pages}/15">尾页</a>
          </li>
        </c:if>
      </ul>
    </div>
  </div>
</div>


PageHelper遇到问题可以参考:https://www.cnblogs.com/my12/p/10096076.html

PageHelper分页失效原因:https://blog.csdn.net/qq_40995335/article/details/80845914

原文地址:https://www.cnblogs.com/IT_CH/p/12357660.html

时间: 2024-08-02 15:55:21

多表查询分页[多次查询]的相关文章

Django-rest-framework多条件查询/分页/多表Json

Django-rest-framework多条件查询/分页/多表Json django-rest-framework多条件查询需要覆写ListAPIView.get_queryset方法,代码示例: def get_queryset(self):     """     使用request.query_params实现多条件查询,也可以使用django filter ,较简单的     方法是在filter_fields中指定要过滤的字段,但只能表示等值,不灵活,灵活的方式是

RDIFramework.NET 中多表关联查询分页实例

RDIFramework.NET 中多表关联查询分页实例 RDIFramework.NET,基于.NET的快速信息化系统开发.整合框架,给用户和开发者最佳的.Net框架部署方案.该框架以SOA范式作为指导思想,作为异质系统整合与互操作性.分布式应用提供了可行的解决方案. 分页非常的常见,基本任何项目都会涉及到分页,这没什么好谈的,大多数我们分页对单表的分页比较多,对多表的分页我们可以通过视图来实现,当然还有其他的方式,在这儿,我以一个实例展示下使用我们的RDIFramework.NET来实现多表

phpcms 多表查询分页

phpcms 多表查询分页,今天放在这里和大家一起分享下.这个函数写在mode.class.php里面,可能不利于升级.直接看代码吧 /**根据SQL查询多表数据并分页,用于多表查询 * @param $sql * @param $order * @param $page * @param $pagesize * @return unknown_type */ final public function mutlilistinfo($sql = '', $page = 1, $pagesize

.net通用CMS快速开发框架——问题:Dapper通用的多表联合分页查询怎么破?

最近在弄一个东东,类似那种CMS的后台管理系统,方便作为其它项目的初始化框架用的. 现在遇到个问题,如标题所示:Dapper通用的多表联合分页查询怎么破? 单表的话很简单就可以实现,多表不通用的话也可以很方便的实现,那么如果多表通用的话,怎么办呢? 难道只能通过拼接sql或者使用存储过程吗?我先来展示下我的实现方式,希望你有更好的方式,然后同我分享一下,以便解决我的困扰. 技术选型:MVC5.Mysql.Dapper.Autofac.Layui.阿里巴巴矢量库.T4(后面补上). 我选择的都是轻

sql row_number() 多表联合分页查询

有三个表 Discuss_Table Talk_Table User_Table 然后查询出三个表的所有内容或者可以查询部分内容.下面的语句是测试过的,拿出来分享下! select * from(select row_number() over(order by D_id desc)as rownum,a.*,b.*,c.* from(Discuss_Table as a inner join Talk_Table as b on a.Titleid=b.T_id)join User_Table

Hibernate的几种查询方式-HQL,QBC,QBE,离线查询,复合查询,分页查询

HQL查询方式 这一种我最常用,也是最喜欢用的,因为它写起来灵活直观,而且与所熟悉的SQL的语法差不太多.条件查询.分页查询.连接查询.嵌套查询,写起来与SQL语法基本一致,唯一不同的就是把表名换成了类或者对象.其它的,包括一些查询函数(count(),sum()等).查询条件的设定等,全都跟SQL语法一样. 示例: Session session = SessionFactory.getCurrentSession(); User user = null; Transaction ts = s

19 MySQL概念 数据库 数据表 数据类型 增加删除修改查询 WHERE Order By Limit

数据库管理系统DBMS 数据库中相关概念 数据库 数据表 记录 字段 数据 登录和退出MySQL客户端 查询自己的MySQL服务器有几个数据库 二.退出MySQL客户端的命令 修改root用户的密码 在MySQL客户端来修改密码(当前账号的密码) 数据库操作 创建数据库 显示所有数据库 删除数据库 选择数据库 更改数据库默认字符集 数据表操作 显示当前数据库中的所有表 创建数据表 显示表的创建 列的常用属性 修改数据表 删除数据表 显示表结构 MySQL数据类型 整型 浮点型 字符型 文本型 日

thinkphp分页时保持查询条件

thinkphp 查询数据时需要分页显示时,会出现只有第1页是按查询条件查到的数据,而其他页面都恢复了,我们想要的结果却是:在翻页时,查询条件保持不变. 原因是:在分页跳转的时候,没有将查询条件作为分页参数传递到下一页.原来翻页的时候,存储在REQUEST变量中的参数并未被传递到下一页,因为表单的 method = “post”,而点击进入下一页时,很明显form表单被重置了,所以打印REQUEST变量也是空的. thinkphp RBAC的示例代码中给出了: PHP $p = new Page

jdbc案例_分页_条件查询

客户信息增删改查系统 软件工程开发流程:1.瀑布模型 2.螺旋模型 RUP (Rational Unified Process,统一软件开发过程 ) 采用瀑布模型: 需求 --- 需求分析 --- 系统设计(概要.详细设计)---- 编码 --- 测试 --- 实施 --- 维护 * 瀑布模型 缺陷在编码结束之前,客户看不到最终软件产品 ,如果需求.设计出现明显错漏,导致软件后期无法维护,存在重大缺陷 * 瀑布模型对于 新型软件,需求不定软件 风险较大 敏捷开发理念:迭代开发模式 ,将系统功能分