how2j.cn


工具版本兼容问题
随着数据中记录的增多,网页上显示的数据会越来越多。

当多到一定程度的时候,就会影响用户的体验。

解决办法是通过分页技术,一次只显示数据库中的部分数据,如果要看其他数据,可以通过"下一页" "最后一页" 等翻页操作实现

步骤 1 : 首先准备 DAO   
步骤 2 : 只显示5条数据   
步骤 3 : 下一页   
步骤 4 : 上一页   
步骤 5 : 第一页   
步骤 6 : 最后一页   
步骤 7 : 边界处理   
步骤 8 : 套上Bootstrap   

步骤 1 :

首先准备 DAO

在DAO中提供方法

public List<Hero> list(int start, int count)

start表示开始的个数,count表示取多少条
比如 list(0, 5) , 即表示第一页,每页有5条数据
比如 list(5, 5) , 即表示第二页,每页有5条数据
package dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import bean.Hero; public class HeroDAO { public int getTotal() { int total = 0; try { Class.forName("com.mysql.jdbc.Driver"); Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8", "root", "admin"); Statement s = c.createStatement(); String sql = "select count(*) from hero"; ResultSet rs = s.executeQuery(sql); while (rs.next()) { total = rs.getInt(1); } System.out.println("total:" + total); s.close(); c.close(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return total; } public void add(Hero hero) { try { Class.forName("com.mysql.jdbc.Driver"); Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8", "root", "admin"); String sql = "insert into hero values(null,?,?,?)"; PreparedStatement ps = c.prepareStatement(sql); ps.setString(1, hero.name); ps.setFloat(2, hero.hp); ps.setInt(3, hero.damage); ps.execute(); ResultSet rs = ps.getGeneratedKeys(); if (rs.next()) { int id = rs.getInt(1); hero.id = id; } ps.close(); c.close(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void update(Hero hero) { try { Class.forName("com.mysql.jdbc.Driver"); Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8", "root", "admin"); String sql = "update hero set name= ?, hp = ? , damage = ? where id = ?"; PreparedStatement ps = c.prepareStatement(sql); ps.setString(1, hero.name); ps.setFloat(2, hero.hp); ps.setInt(3, hero.damage); ps.setInt(4, hero.id); ps.execute(); ps.close(); c.close(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void delete(int id) { try { Class.forName("com.mysql.jdbc.Driver"); Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8", "root", "admin"); Statement s = c.createStatement(); String sql = "delete from hero where id = " + id; s.execute(sql); s.close(); c.close(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public Hero get(int id) { Hero hero = null; try { Class.forName("com.mysql.jdbc.Driver"); Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8", "root", "admin"); Statement s = c.createStatement(); String sql = "select * from hero where id = " + id; ResultSet rs = s.executeQuery(sql); if (rs.next()) { hero = new Hero(); String name = rs.getString(2); float hp = rs.getFloat("hp"); int damage = rs.getInt(4); hero.name = name; hero.hp = hp; hero.damage = damage; hero.id = id; } s.close(); c.close(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return hero; } public List<Hero> list() { return list(0, Short.MAX_VALUE); } public List<Hero> list(int start, int count) { List<Hero> heros = new ArrayList<Hero>(); try { Class.forName("com.mysql.jdbc.Driver"); Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8", "root", "admin"); String sql = "select * from hero order by id desc limit ?,? "; PreparedStatement ps = c.prepareStatement(sql); ps.setInt(1, start); ps.setInt(2, count); ResultSet rs = ps.executeQuery(); while (rs.next()) { Hero hero = new Hero(); int id = rs.getInt(1); String name = rs.getString(2); float hp = rs.getFloat("hp"); int damage = rs.getInt(4); hero.id = id; hero.name = name; hero.hp = hp; hero.damage = damage; heros.add(hero); } ps.close(); c.close(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return heros; } }
步骤 2 :

只显示5条数据

修改HeroListServlet

int start = 0;
int count = 5;
List<Hero> heros = new HeroDAO().list(start, count);

即表示只获取5条数据
只显示5条数据
package servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import bean.Hero; import dao.HeroDAO; 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; List<Hero> heros = new HeroDAO().list(start, count); request.setAttribute("heros", heros); request.getRequestDispatcher("listHero.jsp").forward(request, response); } }
步骤 3 :

下一页

HeroListServlet :
通过参数获取start,如果浏览器没有传递参数,就设置为0。
根据start,计算next. next的值就是start+count.
然后把next传递给listHero.jsp

listHero.jsp
在最后面增加一个超链

<a href="?start=${next}">[下一页]</a>

start=${next} 从服务器传递过来的next值
下一页
package servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import bean.Hero; import dao.HeroDAO; 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; try { start = Integer.parseInt(request.getParameter("start")); } catch (NumberFormatException e) { // 当浏览器没有传参数start时 } int next = start + count; List<Hero> heros = new HeroDAO().list(start, count); request.setAttribute("next", next); request.setAttribute("heros", heros); request.getRequestDispatcher("listHero.jsp").forward(request, response); } }
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <table 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> <tr> <td colspan="6" align="center"> <a href="?start=${next}">[下一页]</a> </td> </tr> </table>
步骤 4 :

上一页

HeroListServlet:
根据start,计算pre. pre的值就是start-count.
然后把pre传递给listHero.jsp

listHero.jsp
在下一页前增加一个超链

<a href="?start=${pre}">[上一页]</a>

start=${pre} 从服务器传递过来的pre值
上一页
package servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import bean.Hero; import dao.HeroDAO; 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; try { start = Integer.parseInt(request.getParameter("start")); } catch (NumberFormatException e) { // 当浏览器没有传参数start时 } int next = start + count; int pre = start - count; request.setAttribute("next", next); request.setAttribute("pre", pre); List<Hero> heros = new HeroDAO().list(start, count); request.setAttribute("heros", heros); request.getRequestDispatcher("listHero.jsp").forward(request, response); } }
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <table 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> <tr> <td colspan="6" align="center"> <a href="?start=${pre}">[上一页]</a> <a href="?start=${next}">[下一页]</a> </td> </tr> </table>
步骤 5 :

第一页

只需要修改listHero.jsp即可

增加

<a href="?start=0">[首 页]</a>

因为首页的start永远都是0
第一页
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <table 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> <tr> <td colspan="6" align="center"> <a href="?start=0">[首 页]</a> <a href="?start=${pre}">[上一页]</a> <a href="?start=${next}">[下一页]</a> </td> </tr> </table>
步骤 6 :

最后一页

HeroListServlet:
在HeroListServlet中计算last
last需要根据总数total和每页有多少条数据count来计算得出。

同时,还要看total是否能够整除count
假设总数是50,是能够被5整除的,那么最后一页的开始就是45

if (0 == total % count)
last = total - count;

假设总数是51,不能够被5整除的,那么最后一页的开始就是50

last = total - total % count;


listHero.jsp
在下一页后增加一个超链

<a href="?start=${last}">[末 页]</a>

start=${last} 从服务器传递过来的last值
最后一页
package servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import bean.Hero; import dao.HeroDAO; 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; 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; // 假设总数是50,是能够被5整除的,那么最后一页的开始就是45 if (0 == total % count) last = total - count; // 假设总数是51,不能够被5整除的,那么最后一页的开始就是50 else last = total - total % count; 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); } }
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <table 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> <tr> <td colspan="6" align="center"> <a href="?start=0">[首 页]</a> <a href="?start=${pre}">[上一页]</a> <a href="?start=${next}">[下一页]</a> <a href="?start=${last}">[末 页]</a> </td> </tr> </table>
步骤 7 :

边界处理

上一页,下一页有一个问题,
如果在第一页点击上一页,就会看不到数据了,因为在第一页的时候,pre=-5,也就导致传递到serlvet的start=-5;
同样的在最后一页的时候,点击下一页,也有类似的问题。

解决办法是进行边界处理:

pre = pre < 0 ? 0 : pre;

如果pre是负数了,就使用0

next = next > last ? last : next;

如果next大于last,就使用last
package servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import bean.Hero; import dao.HeroDAO; 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; 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; if (0 == total % count) 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); } }
步骤 8 :

套上Bootstrap

套上Bootstrap
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%> <!DOCTYPE html> <script src="http://how2j.cn/study/js/jquery/2.0.0/jquery.min.js"></script> <link href="http://how2j.cn/study/css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet"> <script src="http://how2j.cn/study/js/bootstrap/3.3.6/bootstrap.min.js"></script> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <script> $(function(){ $("a").addClass("btn btn-default btn-xs"); }); </script> <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}">编辑</a></td> <td><a href="deleteHero?id=${hero.id}">删除</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> </ul> </nav>


HOW2J公众号,关注后实时获知布最新的教程和优惠活动,谢谢。


问答区域    
2018-03-28 套上bootstrap后,得不到站长的效果
Souyl
关于 J2EE-MVC-分页 的提问



就是表格里的“编辑”和“删除”,没有按钮的边框效果
<%@page language="java" contentType="text/html; charset=UTF-8" 
pageEncoding="UTF-8" import="java.util.*"%>

<script type="text/javascript" src="js/jquery/2.0.0/jquery.min.js"></script>
<link rel="stylesheet" href="css/bootstrap/3.3.6/bootstrap.min.css"></link>
<script  type="text/javascript" src="js/bootstrap/3.3.6/bootstrap.min.js"></script>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<title>List Hero</title>

<script>
	$(function(){
		$("a").addClass("btn btn-defalut btn-xs");
	});
</script>

<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>
	</ul>
</nav>

							






答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到





2018-01-24 <a href="?start=${pre}">[上一页]</a>
junxiaoge
关于 J2EE-MVC-分页 的提问
为什么不写listHero也可以调 好迷 有什么区别 <a href="?start=${pre}">[上一页]</a>和 <a href="listHero?start=${pre}">[上一页]</a>区别




1 个答案

undefeatedQ 答案时间:2018-03-09
看的时候同样的疑问,查了一下,当指向页面为当前页面时,可以省略。 比如当前页面是127.0.0.1/listHero , <a href="?start=${pre}"> ,在点击上一页时会自动加到当前页后面,即为 127.0.0.1/listHero?start=xxx




答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到




2017-11-30 用<c-if test="${pre>=0}">来控制边界时上一页的显示与隐藏,这样符合mvc要求吗
2017-11-14 首次访问,没有传参start,应该会进入catch里面呀
2017-10-27 <a href="?start=${next}">[下一页]</a>
2017-10-14 到边界了是不是应该直接让碰触边界的“上一页”或者"下一页"链接消失或者黑掉啊
2017-09-11 <a href="?start=${pre}">[上一页]</a>
2017-09-08 是不有点问题?
2017-07-08 为什么会有request.getParameter("start")
2017-06-05 <c:forEach > 为什么我在 eclipse里遍历不出来结果
2017-02-02 这样能传到值吗?为啥我的不显示




提问之前请登陆
关于 J2EE-MVC-分页 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 620943819
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: http://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图