• 【oralce/springboot/jquery】自行实现分页


    现在分页控件很多,可我一个也不想用,因为...就是这么倔。好了,废话少说,下面正文开始。

    要分页,需要后台,服务和前台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

  • 相关阅读:
    shell变量解析
    visual studio code(vscode)使用
    linux虚拟机安装
    算法总结系列之八:复读机的故事散列表及其在.NET中的应用浅析(上集)
    对改善Dictionary时间性能的思考及一个线程安全的Dictionary实现
    算法总结系列之八:复读机的故事 散列表.NET应用的研究(下集)
    使用WiX打包你的应用程序之二向WiX脚本传递信息(属性)的几种方式
    当心Dictionary带来的一种隐式内存泄漏
    从DWG到XAML (II) DWFx格式解析及其和XPS的关系
    从DWG到XAML (I) 浅谈DWG历史,现状及方向
  • 原文地址:https://www.cnblogs.com/heyang78/p/15521448.html
Copyright © 2020-2023  润新知