毕设IDEA2019之ssm详解分页功能(凭实力分页)

在实际开发中我们经常会用到表格展示数据,那么问题来了,当数据比较多的时候,每次查看都加载全部数据会严重影响系统性能,用户大部分时候也只是查看某几条数据,不需要加载全部数据。分页能比较好的解决这个问题,一次加载只加载一定数量的数据,提高系统性能和用户体验。比较常用的分页实现方法是使用PageHelper分页插件。所以本篇我们就不用了,自己写,凭实力分页。
前置条件:耐性100%;IDEA2019;jstl标签;EL表达式;ssm框架;lombok插件(也可以自己写get/set方法)

创建一张数据不少的表

这里我用了之前学爬虫时候爬下来的一张表(几百条数据),盆友们可以自己建一张表写点数据
在这里插入图片描述

数据库实现分页

说到数据库分页应该很多盆友就想到了—— LIMIT
从0开始,显示10条数据
在这里插入图片描述
接下来程序实现的分页功能走到最后其实就是实现这条分页sql语句

创建对应的实体类

没用lombok也可以自己写get/set方法

package com.ssm.domain;

import lombok.Data;

/**
 * @author Mr.锵
 * date 2020-04-22
 */
@Data
public class Movie {
    private Integer id;
    private String mname;
    private String mdesc;
    private String mimg;
    private String mlink;
}

创建Dao接口

这里想想我们需要什么,分页的数据(毋庸置疑),怎么知道分多少页?得知道总共有多少条数据

    /**
     * 分页查询电影信息
     * @param num
     * @param size
     * @return
     */
    @Select("select * from movie_resource order by id limit #{num},#{size}")
    List<Movie> findAll(@Param("num") Integer num, @Param("size") Integer size);

    /**
     * 查询总电影数
     * @return
     */
    @Select("select count(1) from movie_resource")
    Integer countAll();

创建service接口及实现方法

接口

package com.ssm.service;

import com.ssm.domain.Movie;

import java.util.List;

/**
 * @author Mr.锵
 * date 2020-04-22
 */
public interface IMovieService {
    /**
     * 分页查询电影信息
     * @param num
     * @param size
     * @return
     */
    List<Movie> findAll(Integer num, Integer size);

    /**
     * 查询总电影数
     * @return
     */
    Integer countAll();
}

实现类

package com.ssm.service.Impl;

import com.ssm.dao.IMovieDao;
import com.ssm.domain.Movie;
import com.ssm.service.IMovieService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author Mr.锵
 * date 2020-04-22
 */
@Service
public class IMovieServiceImpl implements IMovieService {
    @Autowired
    private IMovieDao movieDao;

    @Override
    public Integer countAll() {
        return movieDao.countAll();
    }

    @Override
    public List<Movie> findAll(Integer num, Integer size) {
        return movieDao.findAll(num,size);
    }
}

创建控制器

这里传两个参数page(跳转页数,默认1),size(显示条数,默认10)

package com.ssm.controller;

import com.ssm.domain.Movie;
import com.ssm.service.IMovieService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;

/**
 * @author Mr.锵
 * date 2020-04-22
 */
@Controller
@RequestMapping("/movie")
public class MovieController {
    @Autowired
    private IMovieService movieService;
    @RequestMapping("/findAll")
    public ModelAndView findAll(@RequestParam(required = false,defaultValue ="1")Integer page,
                          @RequestParam(required = false,defaultValue ="10")Integer size){
        Integer countAll = movieService.countAll();
        ModelMap modelMap=new ModelMap();
        Integer num=(page-1)*size;
        List<Movie> all = movieService.findAll(num, size);
        modelMap.addAttribute("movielist",all);//当前页数据
        modelMap.addAttribute("countAll",countAll);//总行数
        ModelAndView mv=new ModelAndView("movie",modelMap);
        return mv;
    }
}

创建jsp页面

  • 这里用了bootstrap框架画表格,可以忽略,搞个表格就行了;

  • 注意,因为用了jstl标签和el表达式,所以要开启一下

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %><%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2020/4/22
  Time: 13:06
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Movie</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.10.0.js"></script>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
    <style>
        table{
            table-layout:fixed;
        }
        td{
            overflow:hidden;
            white-space:nowrap;
            text-overflow:ellipsis;
        }
    </style>
</head>
<body>
<table class="table table-striped table-bordered table-hover">
    <thead>
    <tr>
        <td >编号</td>
        <td>电影名</td>
        <td>描述</td>
        <td>链接</td>
    </tr>
    </thead>
    <tbody>
    <c:forEach items="${movielist}" var="movie">
        <tr>
            <td title="${movie.id}">${movie.id}</td>
            <td title="${movie.mname}">${movie.mname}</td>
            <td title="${movie.mdesc}">${movie.mdesc}</td>
            <td title="${movie.mlink}"><a href="${movie.mlink}">${movie.mlink}</a></td>
        </tr>
    </c:forEach>
    </tbody>
</table>
</body>
</html>

地址栏实现分页

然后就可以通过地址栏直接控制页数和显示条数啦
在这里插入图片描述
在这里插入图片描述
当然,仅仅这样是满足不了我们的需求的,我们还需要什么呢?

  1. 需要知道总共有多少页有多少条数据,当前是第几页;
  2. 解决页数不存在的问题
  3. 一页显示多少条数据;
  4. 通过点击实现跳转,上一页、下一页;
  5. 直接到某一页、去首页、去最后一页;
  6. 自己决定一页显示多少条数据

优化分页功能(controller部分)

主要是在控制器做优化
总条数——直接count函数统计

Integer countAll = movieService.countAll();
modelMap.addAttribute("countAll",countAll);//总条数

每页显示条数——就是传过来的size,但是要判断是否有效,且需要在总页数前,因为size做分母,不能为0

if(size<=1){
            size=1;
        }else if (size >= countAll) {
            size=countAll;
        }
modelMap.addAttribute("page_size",size);//每页显示行数

总页数——总条数/每页显示条数,有余数则加一

Integer add=0;
        if(countAll%size!=0){
            add =1;
        }
        Integer total = (countAll/size)+add;
modelMap.addAttribute("page_total",total);//总页数

当前页数——就是传过来的page,但是要判断是否有效

if(page<=1){
            page=1;
        }else if(page>=total){
            page = total;
        }
modelMap.addAttribute("page_now",page);//当前页        

控制jsp页面显示第几页到第几页——设置begin和end两个参数,默认显示5个页码(细品)

int begin = page-2;
if(begin<1)begin=1;
int end =begin+4;
if(end>total)end = total;
if(end<=5)begin = 1;
else begin = end-4;
modelMap.addAttribute("begin",begin);//开始页数
modelMap.addAttribute("end",end);//结束页数

通过modelandview传到movie.jsp

modelMap.addAttribute("movielist",all);//当前页数据
modelMap.addAttribute("page_now",page);//当前页
modelMap.addAttribute("page_total",total);//总页数
modelMap.addAttribute("page_size",size);//每页显示行数
modelMap.addAttribute("countAll",countAll);//总行数
modelMap.addAttribute("begin",begin);//开始页数
modelMap.addAttribute("end",end);//结束页数
ModelAndView mv=new ModelAndView("movie",modelMap);

优化分页功能(jsp部分)

controller把数据传过来后就进行布局吧

当前:${page_now}&nbsp;总共:${page_total}页/${countAll}&nbsp;一页显示<input value="${page_size}" class="input_text" style="width: 30px" onfocusout="change_size()">&nbsp;
    <c:if test="${page_now != 1}" var="result">
        <a href="" id="frist">首页</a>&nbsp;
        <a href="" id="pre">上一页</a>&nbsp;
    </c:if>
    <c:forEach var="i" begin="${begin}" end="${end}" step="1">
        <c:if test="${page_now != i}" var="result">&nbsp;<a href="" class="pagelink" onclick="change_page('${i}')">${i}</a>&nbsp;</c:if>
        <c:if test="${!result}" var="result">&nbsp;${i}&nbsp;</c:if>
    </c:forEach>
    <c:if test="${page_now != page_total}" var="result">
        <a href="" id="next">下一页</a>&nbsp;
        <a href="" id="last">尾页</a>
    </c:if>

如无意外,现在表格下面应该就多出这一行了,并且细心的盆友会发现少了“首页”和“上一页”这两个按钮,因为第一页就是首页,我们不需要这两个按钮,所以进行判断去掉,同时我们也可以通过这样把跳转页数控制在有效范围内,那为什么controller还要判断呢,万一用户通过地址栏跳转呢是吧
在这里插入图片描述
当然,现在各个元素都是死的,我们要用JavaScript注入灵魂。

优化分页功能(JavaScript部分)

先来实现a标签的跳转,点击的时候根据对应的id/class对href赋值并进行跳转;

  • 注意 显示的页码数因为是循环赋值的,所以用id的话会很麻烦,这里选用class,点击哪一页,所有的页码数的href属性都会赋予点击页的值,因为href的赋值是一样的,所以还是会跳转到点击的页码数,进而实现功能(给自己鼓掌~)
$(function () {
            $("#frist").click(function () {
                $("#frist").attr("href","../movie/findAll?page=1&&size="+$(".input_text").val()+"")
            });
            $("#last").click(function () {
                $("#last").attr("href","../movie/findAll?page=${page_total}&&size="+$(".input_text").val()+"")
            });
            $("#pre").click(function () {
                $("#pre").attr("href","../movie/findAll?page=${page_now - 1}&&size="+$(".input_text").val()+"")
            });
            $("#next").click(function () {
                $("#next").attr("href","../movie/findAll?page=${page_now + 1}&&size="+$(".input_text").val()+"")
            });
        });
        function change_page(num) {
            $(".pagelink").attr("href","../movie/findAll?page="+num+"&&size="+$(".input_text").val()+"")
        }

然后是自定义每页显示多少条数据,因为select标签不够自由,所以选择了input标签,输入多少条就显示多少条,当然,输入值肯定是要在1~总页数之间的,不在这个范围内的弹框提示错误,这里选择在取消焦点的时候(onfocusout)调用函数实现判断和刷新

function change_size() {
            var input_text=$(".input_text").val();
            if(input_text>=1&&input_text<=${countAll})
            window.location.href="../movie/findAll?page=${page_now}&&size="+$(".input_text").val()+"";
            else {
                alert("请输入正确行数");
                $(".input_text").val("${page_size}")
            }
        }

结尾

好了,现在就可以随心所欲、为所欲为的分页了。坚持看到这里的盆友,不知道有没有觉得自己变牛逼了,绝大部分的分页逻辑就是这样的,pythonDjango框架的分页实现,底层逻辑也差不多是这样的,一通百通。当然,相信很多盆友会觉得这样很麻烦,所以实际开发中我们可以直接用PageHelper分页插件,这个插件就是把这些方法封装了起来,下一篇介绍。

第10篇啦!!!感觉有用就赏个赞呗~

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值