問題描述:
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("¶m." + 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
