【黑馬旅遊網案例】分頁數據查詢顯示分析


在這裏插入圖片描述

在這裏插入圖片描述

一、需求分析

以這個案例爲例,要完成以下需求:

  1. 點擊上方導航欄,查詢對應類別的旅遊路線信息。

  2. 下方顯示分頁欄,內容包括:首頁、上一頁、下一頁、末頁等。

  3. 點擊任意一頁,該頁的內容隨之對應改變。

  4. 顯示總頁數與總記錄數。

  5. 要求分頁欄索引爲10個。

1、【數據表分析】

涉及到的表結構:tab_category和tab_route,通過cid相關聯。

在這裏插入圖片描述

2、【MySQL分頁查詢語句】

select * from 表名 limit 開始索引 , 每頁的條數;

還有一個很容易推得得式子:開始索引 = (當前頁碼 -1)* 每頁顯示的行數。

3、【分頁數據分析】

在這個過程中,牽扯到哪些必要的數據,以及這些數據如何得到。

  • 客戶端發送的請求數據

    • 當前的頁數:currentPage,因爲到時候一定是要根據當前的頁碼來查詢,來翻頁,甚至給按鈕加上樣式。

    • 根據這裏的需求,還需要傳遞對應cid,後端接收之後根據cid查找對應的route。

  • 開發者規定的數據

    • 每頁規定的記錄數:pageSize
  • 數據庫查詢到的數據

    • 總記錄數:totalCount,總記錄數可以根據需要展示頁面,最重要的是,可以通過總記錄數和每頁記錄數計算出總頁碼。
    • 每頁顯示的數據,到時候返回根據cid查詢到的數據。
  • 計算得到的數據

    • 總頁數:totalPage,根據totalCount和pageSize算得。

二、後端代碼實現

1、【PageBean對象封裝】

/**
 * @author Summerday
 *
 * 分頁pagebean對象
 */
public class PageBean<T>{
    //總記錄數
    private Integer totalCount;
    //總頁數
    private Integer totalPage;
    //當前頁碼
    private Integer currentPage;
    //每頁顯示的條數
    private Integer pageSize;
    //每頁顯示的數據集合
    private List<T> list;
	//省略getter和setter方法
}

2、【Servlet層】

/**
 * @author Summerday
 */
@WebServlet("/route/*")
public class RouteServlet extends BaseServlet {
    private RouteService service= new RouteServiceImpl();
    public void pageQuery(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //接收參數
        String currentPageStr = request.getParameter("currentPage");
        String cidStr = request.getParameter("cid");
		//tomcat7需要對get請求參數進行處理
        rname = new String(rname.getBytes("iso8859-1"),"utf-8");
        int cid = 0;
        String nullStr = "null";
        //處理參數
        if(cidStr!=null&&cidStr.length()>0&& !nullStr.equals(cidStr)){
            cid = Integer.parseInt(cidStr);
        }
        int currentPage = 1;
        //處理參數
        if(currentPageStr!=null&&currentPageStr.length()>0){
            currentPage = Integer.parseInt(currentPageStr);
        }
        //處理參數(黑馬視頻中是獲取客戶端的數據,我個人感覺不是很合理,於是直接在服務器賦值10int pageSize = 10;
        //調用service查詢pagebean對象
        PageBean<Route> pb = service.pageQuery(cid, currentPage, pageSize);
        //將pagebean對象序列化爲json返回
        writeValue(pb,response);
        
    }
}

3、【Service層】

/**
 * @author Summerday
 */
public class RouteServiceImpl implements RouteService {
    private RouteDao routeDao = new RouteDaoImpl();
    @Override
    public PageBean<Route> pageQuery(int cid, int currentPage, int pageSize) {
        //封裝pagebean
        PageBean<Route> pb = new PageBean<>();
        //設置當前頁碼
        pb.setCurrentPage(currentPage);
        //設置每頁顯示條數
        pb.setPageSize(pageSize);
        //設置總記錄數
        int totalCount = routeDao.findTotalCount(cid);
        pb.setTotalCount(totalCount);
        //設置當前頁顯示的數據集合
        //開始的記錄數
        int start = (currentPage - 1) * pageSize;
        List<Route> list = routeDao.findByPage(cid, start, pageSize);
        pb.setList(list);
        //(剛好除盡的情況)設置總頁數 = 總記錄數/每頁顯示條數
        int totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;
        pb.setTotalPage(totalPage);
        //返回PageBean對象
        return pb;
    }
}

4、【Dao層】

/**
 * @author Summerday
 */
public class RouteDaoImpl implements RouteDao {

    private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
    /**
     * 計算總記錄數
     * @param cid cid
     * @return 總記錄數
     */
    @Override
    public int findTotalCount(int cid) {
        String sql = "select count(*) from tab_route where cid = ?";
        //返回一個值,用forObject
        return template.queryForObject(sql,Integer.class,cid);
    }

    /**
     * 查詢每頁的數據信息
     * @param cid cid
     * @param start 開始索引
     * @param pageSize 每頁的記錄數
     * @return 每頁的數據信息
     */
    @Override
    public List<Route> findByPage(int cid, int start, int pageSize) {
        String sql = "select * from tab_route where cid = ? limit ? , ?";
        return template.query(sql,new BeanPropertyRowMapper<>(Route.class),cid,start,pageSize);
    }
}

三、前臺代碼實現

該案例前臺視圖層使用的是html頁面,因此無法從域中獲取數據,遂用過發送異步ajax請求實現前後端數據交互。

1、【封裝獲取請求參數的方法】

//根據傳遞過來的參數name獲取對應的值
function getParameter(name) {
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)","i");
    var r = location.search.substr(1).match(reg);
    if (r!=null) return (r[2]); return null;
}

設定導航欄中的鏈接爲:var li = '<li><a href="route_list.html?cid='+data[i].cid+'">'+data[i].cname+'</a></li>';

就可以通過getParameter方法將cid獲取,實現cid的傳遞。

2、【異步ajax請求】

接下來也就是比較關鍵的部分,發送異步ajax請求,以下幾種情況都需要發送請求:

  • 頁面加載完成後發送。
  • 點擊頁碼按鈕時發送。

於是就想到將他抽取爲一個方法。

function load(cid, currentPage) {
    //發送ajax請求,請求route/pageQuery,傳遞cid
    $.get("route/pageQuery", {cid: cid, currentPage: currentPage}, function (pb) {
        //分頁工具條的數據展示
        
        //展示總頁碼+總記錄數(黑馬提供的數據庫只有cid=5的數據)
        $("#totalPage").html(pb.totalPage);
        $("#totalCount").html(pb.totalCount);
        var lis = "";
        var firstPage = '<li οnclick="javascript:load('+cid+',1)" style="cursor: pointer"><a href="javascript:void(0)">首頁</a></li>';
        //上一頁的序號,如果爲第一頁,就設置爲第一頁
        var beforeNum = pb.currentPage - 1;
        if (beforeNum <= 0) {
            beforeNum = 1;
        }
        var prevPage = '<li οnclick="javascript:load(' + cid + ',' + beforeNum + ')" style="cursor: pointer" class="threeword"><a href="#">上一頁</a></li>';
        lis += firstPage;
        lis += prevPage;
        //展示分頁頁碼

        /*
        一共展示10個頁碼,能夠達到前五後四的效果
        如果前面不夠5個後面補齊10個
        如果後面不足4個,前面補齊10ge
        */

        //定義開始位置begin.結束位置end
        var begin;
        var end;

        if(pb.totalPage<10){
            //總頁碼<10
            begin = 1;
            end = pb.totalPage;
        }else{
            //總頁碼>=10
            begin = pb.currentPage-5;
            end = pb.currentPage+4;
            //前面不夠5個,後面補齊10個
            if(begin<1){
                begin = 1;
                end = begin+9;
            }
            //後面不足4個,前面補齊10個
            if(end>pb.totalPage){
                end = pb.totalPage;
                begin = end-9;
            }
        }
        for (var i = begin; i <= end; i++) {
            var li;
            //爲當前頁碼加上樣式
            if (pb.currentPage == i) {
                li = '<li class="curPage" style="cursor: pointer" οnclick="javascript:load(' + cid + ',' + i + ')"><a href="javascript:void(0)">' + i + '</a></li>';
            } else {
                //創建頁碼的li
                li = '<li style="cursor: pointer" οnclick="javascript:load(' + cid + ',' + i + ')"><a href="javascript:void(0)">' + i + '</a></li>';
            }
            //拼接字符串
            lis += li;
        }
        var nextNum = currentPage + 1;
        if (nextNum > pb.totalPage) {
            nextNum = pb.totalPage;
        }
        var nextPage = '<li οnclick="javascript:load(' + cid + ','+nextNum+')" style="cursor: pointer" class="threeword"><a href="javascript:void(0);">下一頁</a></li>';
        var lastPage = '<li οnclick="javascript:load(' + cid + ','+pb.totalPage+')" style="cursor: pointer" class="threeword"><a href="javascript:void(0);">末頁</a></li>';
        lis += nextPage;
        lis += lastPage;
        //將list內容設置到ul中
        $("#pageNum").html(lis);
        //列表數據展示
        var route_lis = "";
        for (var i = 0; i < pb.list.length; i++) {
            //獲取{rid:1,rname:"xxx"}
            var route = pb.list[i];
            var li = "省略具體信息。。。,例如route.rimage、route.rname等"
            route_lis += li;
        }
        $("#route").html(route_lis);
        //定位到頁面頂部
        window.scrollTo(0,0);
    })
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章