一、分页操作
mysql的分页查询语句:
select * from tablename limit index, pageNum
index是表示从表中的第几条数据开始查找
pageNum表示每页多少条数据
注意: 数据库中第一条数据编号为0
二、分页显示数据
1.这是最原始的数据,开始时全部都显示
原因:初始时ListHeroServlet当中是这么写的
List<Hero> heros = new HeroDAO().list();
也就说一开始调用的是不带任何参数的list()方法,而HeroDAO中的list()方法又调用了list(0, Short.MAX_VALUE)方法,也就是说此时我们并不是没有进行分页(只是因为我们的数据太少而看不到效果而已),而是因为没有传参,就进行了默认的分页操作。(从第0条数据开始,每页显示MAX_VALUE=127条数据)
public List<Hero> list() {
return list(0, Short.MAX_VALUE);
}
2.对ListHeroServlet进行修改,让其只显示五条数据。
int start = 0;
int count = 5;
List<Hero> heros = new HeroDAO().list(start,count);
这就是第二个效果与第一个效果不同的地方,因为我们指定了数据的从第几条开始分页(start)且每页显示的条数(count)。
但是以上有一个缺陷是:我们的数据start和count都是写死了的,因此我们需要再做出一些改进。
3.下一页
分析:
int start = 0;
int count = 5;
//在分页的过程中,真正变化着的是start,count一直都不变
try {
start = Integer.parseInt(request.getParameter("start"));
} catch (NumberFormatException e) {
// 当浏览器没有传参数start时
}
在获取参数的时候我们需要捕获一个异常,否则由于浏览器最开始跳转到listHero.jsp页面时,由于我们没有点击下一页,因此这个时候是没有start这个参数的。
如果我们此时没有传入参数,那么此时的start就是0。
<tr>
<td colspan="6" align="center">
<a href="?start=${next}">[下一页]</a>
</td>
</tr>
需要注意的是,我们在传start时,使用的是超链接的href属性在进行传参,此时如果我们想要取到这个参数是通过request.getParameter("start"),这个没毛病。
当我点击下一页的时候,在eclipse的左下方自动会出现这样一个地址“http://localhost:8080/MVC/listHero?start=5”。
因此我总结(不知正确与否):在使用a标签的href进行跳转时,?前面没有地址的参数,就代表是对当前地址传参,这就是为什么我们点击下一页的时候会出现不同的页面的原因。(因为start更新了,它就会根据地址重新回到servlet然后再次执行分页的操作。)
4.上一页
HeroListServlet:
根据start,计算pre. pre的值就是start-count.
然后把pre传递给listHero.jsp
5.第一页
首页的更改就比较简单了,只需要修改listHero.jsp页面,将start的值设置为0就可以了。
6.最后一页
HeroListServlet:
在HeroListServlet中计算last
last需要根据总数total和每页有多少条数据count来计算得出。
注:last指的是最后一页数据的起始位置
同时,还要看total是否能够整除count
7.边界处理
上一页,下一页有一个问题。
如果在第一页点击上一页,就会看不到数据了,因为在第一页的时候,pre=-5,也就导致传递到serlvet的start=-5;
同样的在最后一页的时候,点击下一页,也有类似的问题。
解决办法:在将属性放入request作用域之前,对它们做一个判断。
pre = pre < 0 ? 0 : pre;
next = next > last ? last : next;
8.套上BootStrap
注意:分页语句中的order by id desc表示的是首先将所有的数据都按照id逆序排放之后,再确定每条数据的编号进行分页;而不是先按照原数据进行分页操作之后再在每一个分页中按照id的顺序逆序排序。
三、代码
此处我只提供了最重要的两个程序。一个是HeroListServlet,一个是listHero.jsp。另外两个Hero.java和HeroDAO.java就不再提供了。
- HeroListServlet
package servlet;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import bean.Hero;
import dao.HeroDAO;
/*作为控制器的HeroListServlet,其作用就是通过dao获取所有的heros对象,然后放在request中,跳转到listHero.jsp*/
@WebServlet("/HeroListServlet")
public class HeroListServlet extends HttpServlet {
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
int start = 0;
int count = 5; //count是固定的,变化的只是start
try{
start = Integer.parseInt(request.getParameter("start"));
}catch(NumberFormatException e){
//当浏览器没有传参数start时
}
int next = start + count;
int pre = start - count;
//获得总的记录条数
int total = new HeroDAO().getTotal();
int last;//last指的是最后一页数据的起始位置
if(total % count == 0){
last = total - count;
}else{
last = total - total % count;
}
pre = pre < 0 ? 0 : pre;
next = next > last ? last : next;
request.setAttribute("next", next);
request.setAttribute("pre", pre);
request.setAttribute("last", last);
List<Hero> heros = new HeroDAO().list(start,count);
request.setAttribute("heros", heros);
request.getRequestDispatcher("listHero.jsp").forward(request, response);
}
}
- listHero.jsp
<%@ page language="java" import="java.sql.*" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script>
<link href="https://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
<script src="https://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script>
<script>
$(function(){
$("a").addClass("btn btn-default btn-xs");
});
</script>
</head>
<body>
<table style="width:500px; margin:44px auto" class="table table-striped table-bordered table-hover table-condensed"
align="center" border='1' cellspacing='0'>
<tr>
<td>id</td>
<td>name</td>
<td>hp</td>
<td>damage</td>
<td>edit</td>
<td>delete</td>
</tr>
<c:forEach items = "${heros}" var = "hero" varStatus = "st">
<tr>
<td>${hero.id}</td>
<td>${hero.name}</td>
<td>${hero.hp}</td>
<td>${hero.damage}</td>
<td><a href="editHero?id=${hero.id}">edit</a></td>
<td><a href="deleteHero?id=${hero.id}">delete</a></td>
</tr>
</c:forEach>
</table>
<nav>
<ul class="pager">
<li><a href="?start=0">首 页</a></li>
<li><a href="?start=${pre}">上一页</a></li>
<li><a href="?start=${next}">下一页</a></li>
<li><a href="?start=${last}">末 页</a></li>
</td>
</nav>
</body>
</html>
运行代码时需要注意顺序:要先运行HeroListServlet,再运行listHero.jsp页面。且上述的edit和delete其实只是一个展现,真正的功能在这里并没有实现。