话说:
前面一些列的优化,在框架未露尊容之前,已经优化到极致了。今天把这个精致又小巧的功能——分页,总结下,作为礼物送给又年轻一岁的自己。
目标:
新闻信息分页显示
一、Pager类
二、修改BaseDao
三、NewsDao
四、NewsServlet
五、页面显示newsShow.jsp
六、总结
整体布局还是建立在前面JavaWeb_Servlet的最终优化版本基础之上
最终的效果图
在此,要感谢当年传递知识的老师,感谢百度的技术人员,有了你们的产品,才得以模仿和学习。
整体思路:
创建一个Pager类,里面封装分页所需要的各种属性(pageIndex\pageSize\Count\offset\start\end)等等;根据实际情况修改NewsDao,BaseDao,主要修改NewsDao的查的方法(之前是全部显示),页面也稍作调整。
一、Pager类
把整个分页封装起来,非常便于调用。
package com.hmc.jdbc.news.model;
import java.util.List;
/**
* User:Meice
* 2017/10/12
*/
public class Pager<E> {
private int totalPage;//总页数
private int pageSize=5;//显示条目
private int count;//总记录数
private int pageIndex=1;//当前页
private int offset;//分页偏移量(limit(offset,pageSize))
private int start;
private int end;
private List<E> datas;//记录数据
public int getTotalPage() {
totalPage= (int) Math.ceil((double) count/pageSize);
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public int getPageIndex() {
return pageIndex;
}
public void setPageIndex(int pageIndex) {
if(pageIndex<=5) {
start = 1;
end = 5;
}else if(pageIndex == getTotalPage()) {
start = pageIndex-4;
end = pageIndex;
}else if(pageIndex>5) {
start = pageIndex-2;
end = pageIndex +2;
}else {
}
this.pageIndex = pageIndex;
}
public int getOffset() {
offset = (pageIndex-1)*pageSize;
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getEnd() {
return end;
}
public void setEnd(int end) {
this.end = end;
}
public List<E> getDatas() {
return datas;
}
public void setDatas(List<E> datas) {
this.datas = datas;
}
public static void main(String[] args) {
// System.out.println("我是两个整数的运算结果:"+Math.ceil(506/5));
// System.out.println("我是double和整数的运算结果:"+Math.ceil((double)506/5));
}
}
二、修改BaseDao
这里面只是在前期基础上增加了一个executeCount()的方法,目的是用来求新闻显示的总条目数,没有count,就无法计算pageSize。
另外,顺便也把获取PreparedStatement对象的方法封装为了getPs()方法。
package com.hmc.jdbc.news.dao;
import com.hmc.jdbc.news.model.Goods;
import com.hmc.jdbc.news.model.News;
import com.hmc.jdbc.news.util.ConfigUtil;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
//哎呀,默认导全部的包,如果包到错了怎么办?
public class BaseDao {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
//1、加载驱动,把加载类定义为静态语句块
static {
try {
Class.forName(ConfigUtil.get("driver"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//说实话感觉卡顿的问题也没怎么解决。可能搜狗输入法还没有和捷克公司做好沟通吧。
}
//2、连接MySQL数据库 定义方法getConn()
public Connection getConn() {
String url = ConfigUtil.get("url");
String user = ConfigUtil.get("user");
String password = ConfigUtil.get("password");
try {
conn = DriverManager.getConnection(url,user,password);
} catch (SQLException e) {
e.printStackTrace();
}
System.out.print("恭喜你,连接上了....");
return conn;
}
//3、关闭资源
public void closeJDBC(ResultSet rs, PreparedStatement ps,Connection conn) {
try {
if (rs != null) rs.close();
if (ps != null) ps.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//编写查 把数据库的News输出到控制台
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
BaseDao bd = new BaseDao();
//这里如果赋值,就会报NullPoint错误。
conn = bd.getConn();
try {
//预编译SQL语句
String sql = "select * from t_news";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
//遍历结果集
while(rs.next()){
//这里我们可以分明感受到Idea和Eclipse的差别
int id = rs.getInt(1);
String title = rs.getString("title");
String author = rs.getString("author");
System.out.println(id+"---"+title+"---"+author);
}
} catch (SQLException e) {
e.printStackTrace();
}
new BaseDao().test();
}
/**
* 我们会发现,我们发现,在NewsDao里面,尤其是CUD有大量重复代码,他们结构都差不多,不同的只是Sql语句和SQL带的参数。所以我们可以做如下封装。
*另外,NewsShow中的查询和改(U)代码也几乎完全相同,无非一个是
* select * from t_news ;一个是select * from t_news where id = ? 是否也可以类似CUD那样封装起来?
*
*/
public int CUD(String sql,Object[] params){
int result = 0;
getConn();
try {
ps = conn.prepareStatement(sql);
//问题关键是参数怎么赋值?在参数个数不确定?类型不确定的情况下?
for (int i=0;i<params.length;i++) {
ps.setObject((i+1),params[i]);
}
result = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
closeJDBC(null,ps,conn);
return result;
}
//下面们把查在优化一下
/**
* 这里我们不把SQL写死,我们会在两个地方用到,1是newsShow.jsp用到,
* 另外一个是修改新闻的时候要用到,代码区别仅仅只是SQL语句不同。
*/
public List<News> listShow(String sql, Object[] params) {
List<News> list = new ArrayList<>();
getConn();
try {
ps = conn.prepareStatement(sql);
/**
* 以下方法解决了参数个数和参数类型不同的问题
* 高度抽象,不论你给多少参数,什么类型,都可以处理。
*/
//这里的params可能有,也可以没有比如select * from t_news和select * from t_news where id = ?
//所以最好判断一下
if(params != null && params.length>0) {
for(int i = 0;i<params.length;i++) {
ps.setObject((i+1),params[i]);
}
}
//否则(null),就不用给参数赋值了,直接执行,这样逻辑才够严谨。
rs = ps.executeQuery();
while (rs.next()) {
int id = rs.getInt("id");
String title = rs.getString(2);
String author = rs.getString("author");
News news = new News(id,title,author);
list.add(news);
}
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
//再次优化查的方式,把List<E>对象也变得灵活抽象,不写死
public List<?> listShow3(String sql ,Class<?> cls,Object... params) {
//创建集合存放
List<Object> list = new ArrayList<>();
getConn();
try {
//预编译
ps = conn.prepareStatement(sql);
//如果带参,遍历赋值
if(params != null && params.length>0){
for(int i =0;i<params.length;i++) {
ps.setObject((i+1),params[i]);
}
}
//执行SQL
rs = ps.executeQuery();
//获取元数据
ResultSetMetaData rsmd = rs.getMetaData();
//遍历
while (rs.next()) {
/**
* 要解决的问题就在这里
* 我们不知道调用该方法的人会传入什么类?那个类中有什么属性?
* 也同样不知道该用什么类型来接收,也同样没法把属性作为一个对象传递给
* list<E>集合?
*/
//实例化对象
Object obj = cls.newInstance();
//获取列数
int count = rsmd.getColumnCount();
//rs.getObject(这里面的列数通过remd获取);
for(int k=1;k<=count;k++) {
//获取列名
String colName = rsmd.getColumnName(k);
//根据列名获取对象字段
Field f = cls.getDeclaredField(colName);
//给字段赋值;获取列值
Object colVal = rs.getObject(colName);
//给对象赋值
f.setAccessible(true);//取消访问检查
f.set(obj,colVal);
}
list.add(obj);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
closeJDBC(rs,ps,conn);
return list;
}
/*
定义获取分页里面数总数count的方法
背景:因为上面的listShow3()方法只能处理返回是一个对象的,如果我的sql语句变成这样,就没法处理了
select count(id) from t_news;
select count(id) ,title from t_news
这样,listShow3()方法根本就应付不过来....
*/
public int executeCount(String sql ,Object[] params) {
ps = getPs(sql,params);
try {
rs = ps.executeQuery();
if(rs.next()) {
return rs.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
//把获得ps对象也定义为一个方法,避免每次重复写
public PreparedStatement getPs (String sql,Object[] params) {
try {
this.getConn();
ps = conn.prepareStatement(sql);
if(params != null && params.length>0) {
for(int i=0;i<params.length;i++) {
ps.setObject((i+1),params[i]);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return ps;
}
public void test() {
String sql = "select * from t_goods";
List<Goods> list = (List<Goods>) listShow3(sql, Goods.class,null);
System.out.println(list);
}
}
三、NewsDao
这里面最为核心,写了分页显示新闻的方法pageList()和获取新闻总条目数的方法count();其他方法未做改变。
package com.hmc.jdbc.news.dao;
import com.hmc.jdbc.news.model.News;
import com.hmc.jdbc.news.model.Pager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* User:Meice
* 2017/10/1
*/
public class NewsDao extends BaseDao{
//这个类里面我们要写CURD啦。
//1 查 R
/**
* 我们要把数据从刚才的控制台输出变为输出到页面,所以需要一个类似容器的东西存放我们的数据
* 这里我们用List集合来存放新闻信息,作为运输工具。把我们的代码运输到JSP页面。
*/
public List<News> list() {
List<News> list = new ArrayList<>();
getConn();
String sql = "select * from t_news";
try {
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()) {
int id = rs.getInt(1);
String title = rs.getString("title");
String author = rs.getString("author");
//每次遍历一次,我们就把一行新闻作为一个对象,这就是JavaBean
News news = new News(id,title,author);
list.add(news);
}
} catch (SQLException e) {
e.printStackTrace();
}
//输出做验证,看以上代码是否正确
// System.out.println(list);
closeJDBC(rs,ps,conn);
return list;
}
//法二:查 (写了listShow3()之后,调用多方便!)
public List<News> list2 () {
String sql = "select * from t_news";
List<News> list2 =(List<News>) listShow3(sql,News.class,null);
return list2;
}
//以下写分页的查询
public Pager<News> pageList(Pager<News> pager) {
String sql = "select * from t_news limit ?,?";
Object[] params = {pager.getOffset(),pager.getPageSize()};
List<News> list =(List<News>) listShow3(sql,News.class,params);
pager.setDatas(list);
//把count存放进去
pager.setCount(count());
return pager;
}
//写方法获取count(总条目数)
/*
目前为止,pageIndex可以通过页面点击传参获取;offset通过pageIndex计算出来了:pageSize是目前是
固定的,就差总条目数
*/
/* public int count() {
String sql = "select count(id) from t_news ";
//这里的问题就是,这里查询的不是一个对象,只是单独的一个结果,而且
//如果select count(id),title from t_news?呢,该怎么办?我们的方法listShow3()就不适用啦
listShow3(sql,null,null);
}*/
//获取总记录数
public int count() {
String sql = "select count(id) from t_news";
return executeCount(sql,null);
}
public static void main(String[] args) {
NewsDao nd = new NewsDao();
//验证list()方法
// nd.list();
}
//2 增 C
//法1:封装发布新闻的方法
public void newsAdd(News news) {
getConn();
String sql = "insert into t_news (title,author) values (?,?)";
try {
//预编译,步骤类似查 R
ps = conn.prepareStatement(sql);
//这里我们使用?来传递,专业名称忘了
ps.setString(1,news.getTitle());
ps.setString(2,news.getAuthor());
//这里执行和查就不一样了,用的是Update方法
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
closeJDBC(null,ps,conn);
}
//法2:封装发布新闻的方法(前后对比明显吧!)
public int newsAdd2(News news){
String sql = "insert into t_news (title,author) values (?,?)";
Object[] params = {news.getTitle(),news.getAuthor()};
return CUD(sql,params);
}
//3 删 D 法一
public void newsDel(int id) {
getConn();
String sql = "delete from t_news where id = ? ";
System.out.println("进来了");
try {
ps = conn.prepareStatement(sql);
ps.setInt(1,id);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
closeJDBC(null,ps,conn);
}
//删除法二
public int newsDel2(int id) {
String sql = "delete from t_news where id = ?";
Object[] params = {id};
return CUD(sql,params);
}
//4 改 U
//法1:第一步,点击修改链接,我们要能把对应的内容放到对应的位置。
public News newsPut(int id) {
getConn();
News news = null;
String sql = "select * from t_news where id = ?";
try {
ps = conn.prepareStatement(sql);
ps.setInt(1,id);
rs = ps.executeQuery();
while (rs.next()) {
id = rs.getInt(1);
String title = rs.getString(2);
String author = rs.getString(3);
news = new News(id,title,author);
}
} catch (SQLException e) {
e.printStackTrace();
}
closeJDBC(rs,ps,conn);
return news;
}
//法2:封装根据对应ID把新闻放到页面的方法(两方法对比结果鲜明!)
public List<News> newsPut2(int id) {
String sql = "select * from t_news where id = ?";
Object[] params = {id};
return listShow(sql,params);
}
//法3:根据最高级版本的查的的方法listShow3()来根据id获取新闻,直接返回新闻信息,便于获取
public News newsPut3(int id) {
String sql = "select * from t_news where id = ?";
Object[] params = {id};
List<News> list =(List<News>) listShow3(sql,News.class,params);
//判断
if(list != null && list.size()>0) {
return list.get(0);
}else{
return null;
}
}
//执行修改操作 法1:
public void newsUpdate(News news) {
getConn();
String sql = "update t_news set title = ? , author = ? where id = ?";
try {
ps = conn.prepareStatement(sql);
ps.setString(1,news.getTitle());
ps.setString(2,news.getAuthor());
ps.setInt(3,news.getId());
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
closeJDBC(null,ps,conn);
}
//执行修改操作 法2:(没有对比就没有伤害)
public int newsUpdate2(News news) {
String sql = "update t_news set title = ?, author = ? where id = ?";
Object[] params = {news.getTitle(),news.getAuthor(),news.getId()};
return CUD(sql,params);
}
}
四、NewsServlet
进行页面请求处理和页面跳转;主要是新增了方法pageList()
package com.hmc.jdbc.news.servlet;
import com.hmc.jdbc.news.dao.BaseDao;
import com.hmc.jdbc.news.dao.NewsDao;
import com.hmc.jdbc.news.model.News;
import com.hmc.jdbc.news.model.Pager;
import com.hmc.jdbc.news.util.StringConvertUtil;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Connection;
import java.util.List;
/**
* User:Meice
* 2017/10/5
*/
@WebServlet(urlPatterns = "/news.do")
public class NewsServlet extends BaseServlet {
NewsDao nd = new NewsDao();
BaseDao bd = new BaseDao();
//查(R)
// 未避免代码混乱,把显示新闻列表封装成方法;这里采用最高级的显示新闻方法listShow3()
private void list (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String sql = "select * from t_news";
List<News> list =(List<News>) bd.listShow3(sql,News.class,null);
//3 存储到req中
req.setAttribute("list", list);
req.getRequestDispatcher("newsShow.jsp").forward(req, resp);
}
//定义查询分页显示页面的方法pageList()
private void pageList(HttpServletRequest req,HttpServletResponse resp ) {
//接收参数pageIndex
String strPageIndex = req.getParameter("pageIndex");
String strPageSize = req.getParameter("pageSize");
int pageIndex = StringConvertUtil.getVal(strPageIndex);
int pageSize = StringConvertUtil.getVal(strPageSize);
//当时转换方法里面如果为null返回的是0
pageIndex = pageIndex ==0?1:pageIndex;
pageSize = pageSize == 0?5:pageSize;
Pager<News> pager = new Pager<>();
//避免最后页会多出来
pager.setCount(nd.count());
pager.setPageIndex(pageIndex);
pager.setPageSize(pageSize);
//调用pageList()方法
pager = nd.pageList(pager);
//存储到req中
req.setAttribute("pager",pager);
//页面跳转
try {
req.getRequestDispatcher("newsShow.jsp").forward(req,resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//增(C)
private void add(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException {
//接受参数
String title = req.getParameter("title");
String author = req.getParameter("author");
News news = new News(title,author);
int result = nd.newsAdd2(news);//(写这些方法从后往前写)
if(result > 0) {
req.getRequestDispatcher("news.do?op=list").forward(req,resp);
}else {
req.getRequestDispatcher("newsAdd.jsp").forward(req,resp);
}
}
//改(U)
//显示要修改的新闻
public void changeShow(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException {
//接受参数
String strId = req.getParameter("id");
int id = StringConvertUtil.getVal(strId);
News news = nd.newsPut3(id);
req.setAttribute("news",news);
req.getRequestDispatcher("newsUpdate.jsp").forward(req,resp);
}
//执行修改操作
public void change(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException {
//接受参数
String strId = req.getParameter("id");
int id = StringConvertUtil.getVal(strId);
String title = req.getParameter("title");
String author = req.getParameter("author");
News news = new News(id,title,author);
//调用方法
int result = nd.newsUpdate2(news);
if(result >0) {
req.getRequestDispatcher("news.do?op=list").forward(req,resp);
}else {
req.getRequestDispatcher("newsUpdate.jsp").forward(req,resp);
}
}
//删(D)
private void del(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException {
//接受参数
String strId = req.getParameter("id");
int id = StringConvertUtil.getVal(strId);
int result = nd.newsDel2(id);
req.getRequestDispatcher("news.do?op=list").forward(req,resp);
}
}
五、页面显示newsShow.jsp
这个和之前的显示页面相比,变化巨大。亮点在于JSTL运用、参数回显。
<%@ page import="java.util.List" %>
<%@ page import="java.util.Enumeration" %>
<%@ page import="com.hmc.jdbc.news.model.News" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%--
Created by IntelliJ IDEA.
User: Meice
Date: 2017/10/1
Time: 13:30
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--如果不用jstl,还是采用JSP嵌套获取--%>
<%--
<%
//本来在页面,我们获取list集合非常简单,${}这样就获取了,但是实际过程中,我们在JSP代码中没发做到用这个来获取
List<News> list =(List<News>) request.getAttribute("list");
%>
--%>
<html>
<head>
<title>Meice的新闻列表</title>
</head>
<body>
<h2 align="center">Meice的新闻列表</h2><br/>
<a href="newsAdd.jsp">发布新闻</a>
<table border="1" align="center" width="80%">
<thead>
<tr>
<th>编号</th>
<th>标题</th>
<th>作者</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<%--${news}--%>
<%--这里传过来就是那幅图的场景;现在的问题是我不知道怎么接收这个传递过来的值,直接用EL取出来的是
个List<News>的集合。这边又没法遍历。??
如果不用JSTL,我们用普通的for each,问题是怎么取出这个值。
--%>
<c:forEach var="news" items="${pager.datas}">
<tr>
<td align="center">${news.id}</td>
<td align="center">${news.title}</td>
<td align="center">${news.author}</td>
<td align="center">
<a href="news.do?op=changeShow&id=${news.id}">修改</a>
<a href="news.do?op=del&id=${news.id}" onclick="return confirm('真的忍心删我?')">删除</a>
</td>
</tr>
</c:forEach>
<tr>
<td colspan="4" align="center">
<div style="float: left;margin-left: 150px">
<c:if test="${pager.pageIndex>1}">
<a href="news.do?op=pageList&pageIndex=1">首页</a>
<a href="news.do?op=pageList&pageIndex=${pager.pageIndex-1}">上一页</a>
</c:if>
<c:forEach var="pn" begin="${pager.start}" end="${pager.end}">
<c:if test="${pn==pager.pageIndex}">
${pn}
</c:if>
<c:if test="${pn != pager.pageIndex}">
<a href="news.do?op=pageList&pageIndex=${pn}">${pn}</a>
</c:if>
</c:forEach>
<%--EL表达式支持运算--%>
<c:if test="${pager.pageIndex<pager.totalPage}">
<a href="news.do?op=pageList&pageIndex=${pager.pageIndex+1}">下一页</a>
<a href="news.do?op=pageList&pageIndex=${pager.totalPage}">末页</a>
${pager.pageIndex}/${pager.totalPage}
</c:if>
</div>
<%--以下实现页面跳转--%>
<form action="news.do?op=pageList" method="post" style="float:right;margin-right: 200px" >
<input type="text" name="pageIndex" style="width: 30px;height: 30px" value="${param.pageIndex}" />
<select name="pageSize" style="height: 30px">
<option value="5" ${param.pageSize==5?'selected':''}>5</option>
<option value="10" ${param.pageSize==10?'selected':''}>10</option>
<option value="20" ${param.pageSize==20?'selected':''}>20</option>
</select>
<input type="submit" value="Go"style="float: right;height: 30px">
</form>
</td>
</tr>
</tbody>
<tfoot></tfoot>
</table>
</body>
</html>
六、总结
1、利用页面跳转陷入死循环,重复生成大量数据,便于分页。
//增(C)
private void add(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException {
//接受参数
String title = req.getParameter("title");
String author = req.getParameter("author");
News news = new News(title,author);
int result = nd.newsAdd2(news);//(写这些方法从后往前写)
if(result > 0) {
req.getRequestDispatcher("news.do?op=add").forward(req,resp);
}else {
req.getRequestDispatcher("newsAdd.jsp").forward(req,resp);
}
}
之前是跳转到news.do?op=list,这里反复跳转,造成自动不断增加新闻,来回跳!就有大量新闻啦!
2、运算的时候,数据类型默认转换要注意下
否则,在分页的时候,容易计算不准。简单的数学啊………
public static void main(String[] args) {
System.out.println("我是两个整数的运算结果:"+Math.ceil(506/5));
System.out.println("我是double和整数的运算结果:"+Math.ceil((double)506/5));
}
3、页面用到了JSTL表达式:
<c:for each>
<c:if text>
这个主要在页面控制何时显示首页 上一页;末页,下一页以及当前页面不能再点击;
4、控制每页显示的页数,关键在start和end这两个属性,同时这两个属性和pageIndex之间的关系;
5、参数回显——页面刷新,参数就丢失了;用param这个内置对象,实现参数回显
<input type="text" name="pageIndex" style="width: 30px;" value="${param.pageIndex}" />
<select name="pageSize" style="height: 30px">
<option value="5" ${param.pageSize==5?'selected':''}>5</option>
<option value="10" ${param.pageSize==10?'selected':''}>10</option>
<option value="20" ${param.pageSize==20?'selected':''}>20</option>
</select>
<input type="submit" value="Go"style="float: right;height: 30px">
分页功能虽然小巧,但是五脏俱全,细节还是很多呢。
最后,祝福老爸老妈!轻轻告诉你们,孩子在茁壮成长,请放心!