现在分页控件很多,可我一个也不想用,因为...就是这么倔。好了,废话少说,下面正文开始。
要分页,需要后台,服务和前台js、css密切配合,于是正文就分成四部分:
1.后台数据库的部分
数据库部分需要两个函数,一个是查总数量的,一个是查某一页的数据的。
import java.util.List; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.SelectProvider; import com.hy.myapp.Entity.Reputation; @Mapper public interface ReputationMapper { @Select(" select count(*) from mc_reputation where deleted=0 or deleted=1 ") int countAlive(); @SelectProvider(type=ReputationMapperSql.class,method="getPagedQueryAliveSql") List<Reputation> pagedQueryAlive(int start,int end); }
ReputationMapperSql中的具体代码:
public class ReputationMapperSql extends BaseMapperSql{ public String getPagedQueryAliveSql(int start,int end) { return getPagedSql(getAliveAllSql(),start,end); } /** * 取活着的全部 * @return */ public String getAliveAllSql() { StringBuilder sb=new StringBuilder(); sb.append(" select "); sb.append(" a.id, "); sb.append(" a.name, "); sb.append(" a.brief, "); sb.append(" a.deleted, "); sb.append(" to_char(a.create_time,'yyyy-mm-dd hh24:mi:ss') as ctime, "); sb.append(" b.name as creater "); sb.append(" from ( select * from mc_reputation where deleted=0 or deleted=1 ) a "); sb.append(" left join mc_user b "); sb.append(" on a.create_uid=b.id "); sb.append(" order by a.id "); String sql=sb.toString(); return sql; } }
抽象类中的代码:
public abstract class BaseMapperSql { protected String getPagedSql(String realSql,int start,int end) { StringBuilder sb=new StringBuilder(); sb.append(" select * from ( select a.*,rownum as rn from ("); sb.append(realSql); sb.append(" ) a where rownum<="+end); sb.append(" ) b where b.rn>"+start); return sb.toString(); } }
有同学会问查数量的代码能否用select count(*) from getAliveAllSql 这么做,这样功能可以运作,但效率下去一半,不值得。
2.服务部分
import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.hy.myapp.Entity.Reputation; import com.hy.myapp.mapper.ReputationMapper; /** * 用于用户服务的Restful控制器 * @author hy * 2021年11月7日 */ @RestController public class ReputationRestCtrl { @Autowired private ReputationMapper rptnMapper; @RequestMapping(value="/pagedQueryRptn", method=RequestMethod.GET) public Map<String,Object> pagedQueryRptn(int pageNo){ Map<String,Object> retvalMap=new LinkedHashMap<String,Object>(); retvalMap.put("pageNo", pageNo); final int PAGE_SIZE=5; int totalCount=rptnMapper.countAlive(); retvalMap.put("totalCount", totalCount); int pageCount=(int)Math.ceil((double)totalCount/PAGE_SIZE); retvalMap.put("pageCount", pageCount); int start=pageNo*PAGE_SIZE; int end=(pageNo+1)*PAGE_SIZE; List<Reputation> datasInPage=rptnMapper.pagedQueryAlive(start, end); retvalMap.put("rptns", datasInPage); return retvalMap; } }
这部分搞清楚如何将页码转成start、end就够了。
3.页面请求部分
前台会用Ajax往后台调用,这部分相对固定。
// 核心分页函数 function pagedQuery(pageNo){ $.ajax({ url:"/mediacool/pagedQueryRptn", data:{pageNo:pageNo}, type:"get", dataType:"json", timeout:5000, error:function(xhr,textStatus,errorThrown){alert('ajax error')}, success:function(data){ showRptnsInTable("myTable",data.rptns); adjustPagation(data.pageNo,data.pageCount); }, }); }
adjustPagation才是本文重点,在讲述它之前,需要了解页面上的分页按钮是如何构建的。
HTML代码:
<div id="list5pagationDiv" class="pagationDiv"> <ul> <li><a id="prevPageLink" href="#">上一页</a></li> <li><a id="fisrtPageLink" href="#">first</a></li> <li><a id="prevDotsLink" href="javascript:void();" class="noborder">...</a></li> <li><a id="page1Link" href="#">1</a></li> <li><a id="page2Link" href="#">2</a></li> <li><a id="page3Link" href="#">3</a></li> <li><a id="page4Link" href="#">4</a></li> <li><a id="page5Link" href="#">5</a></li> <li><a id="page6Link" href="#">6</a></li> <li><a id="page7Link" href="#">7</a></li> <li><a id="page8Link" href="#">8</a></li> <li><a id="page9Link" href="#">9</a></li> <li><a id="nextDotsLink" href="javascript:void();" class="noborder">...</a></li> <li><a id="lastPageLink" href="#">last</a></li> <li><a id="nextPageLink" href="#">下一页</a></li> </ul> </div>
而相关CSS代码则是:
.pagationDiv{ } .pagationDiv ul{ list-style:none; margin: 0 auto; /*让ul在div中水平居中 */ padding:0; text-align:center; /*让li在ul中水平居中*/ } .pagationDiv ul li{ display:inline-block; height:30px; margin-right:10px; line-height:30px; text-align: center; } .pagationDiv ul li a{ border:1px solid teal; padding-left:5px; padding-right:5px; } .pagationDiv ul li a.noborder{ border:0px solid blue; } .pagationDiv ul li a:hover{ background:navy; color:white; }
看懂了以上两部分,adjustPagation函数就好理解了:
// 调整分页栏 function adjustPagation(pageNo,pageCount){ console.log("总页数="+pageCount); console.log("当前页="+pageNo); // 如果只有一页,那分页div就没必要出来,否则显示 if(pageCount==1){ $("#list5pagationDiv").hide(); return; }else{ $("#list5pagationDiv").show(); } // 上一页,下一页按钮的链接可以及时定夺 $('#prevPageLink').attr('href','javascript:pagedQuery("'+(pageNo-1)+'");'); $('#nextPageLink').attr('href','javascript:pagedQuery("'+(pageNo+1)+'");'); // 如果是第一页,那么上一页就不用显示 if(pageNo==0){ $("#prevPageLink").parent().hide(); }else{ $("#prevPageLink").parent().show(); } // 如果是最后一页,那么下一页就不用显示 if(pageNo==pageCount-1){ $("#nextPageLink").parent().hide(); }else{ $("#nextPageLink").parent().show(); } var begin;// 起始页 var end; // 结束页 //总共显示9个页码 if(pageCount<9){ begin=1; end=pageCount; } else{ begin=pageNo-3; end=pageNo+5; if(begin<1){ begin=1; end=begin+8; } if(end>pageCount){ end=pageCount; begin=end-8; } } console.log("begin="+begin); console.log("end="+end); // 九个钮先隐藏 for(var i=1;i<=9;i++){ var btnId="#page"+i+"Link"; $(btnId).parent().hide(); } for(var i=begin;i<=end;i++){ var btnIdx=i-begin+1; var btnId="#page"+btnIdx+"Link"; $(btnId).text(" "+i+" "); $(btnId).parent().show(); $(btnId).attr('href','javascript:pagedQuery("'+(i-1)+'");'); // 当前页不显示边框,链接失效 if((i-1)==pageNo){ $(btnId).attr("class","noborder"); $(btnId).attr('href','javascript:void();'); }else{ $(btnId).attr("class",""); } } // 1不显示,2不显示,3开始才显示... var value=parseInt($("#page1Link").text()); if(value>=3){ $("#prevDotsLink").parent().show(); }else{ $("#prevDotsLink").parent().hide(); } // 1不显示,2开始才显示首页 if(value>=2){ $("#fisrtPageLink").text("1"); $("#fisrtPageLink").parent().show(); $("#fisrtPageLink").attr('href','javascript:pagedQuery(0);'); }else{ $("#fisrtPageLink").parent().hide(); } // -1(pageCount-1)不显示,-2(pageCount-2)不显示,-3才显示... value=parseInt($("#page9Link").text()); if(value<=pageCount-2){ $("#nextDotsLink").parent().show(); }else{ $("#nextDotsLink").parent().hide(); } if(value<pageCount){ $("#lastPageLink").text(pageCount); $("#lastPageLink").parent().show(); $("#lastPageLink").attr('href','javascript:pagedQuery("'+(pageCount-1)+'");'); }else{ $("#lastPageLink").parent().hide(); } }
注释都有,懂得都懂, 不懂的自己多下工夫吧,有些代码不亲身做一遍是不会悟透的。
最后实现效果:
END