多表查詢分頁[多次查詢]


問題描述:

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM