- 前言
- 一、使用到的开发工具和技术
- 二、MVC模式分页处理
- 1.Web层(应用层,Servlet层)
- 2.Service层(业务层)
- 3.Dao层(持久层)
- 4.数据展示
- 三、总结
前言
在web应用开发中,数据分页是个常见的功能,也是一个极其重要的功能,可以说随处可见。当然对于一个新手来说也是一个难点,下面是我在平常的练习结合一些视频教程,对分页模型的一个拙见。
提示:以下是本篇文章正文内容,下面案例可供参考
一、使用到的开发工具和技术IDEA ,SQLServer2012/Mysql ,Tomcat,JSP。
二、MVC模式分页处理 1.Web层(应用层,Servlet层)1)这里,我使用了反射机制,通过反射获取页面的参数,根据获取的参数,寻找对应的Servlet类的相应处理方法。
代码如下(示例):
public abstract class baseServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 解决post请求中文乱码问题
// 一定要在获取请求参数之前调用才有效
req.setCharacterEncoding("UTF-8");
String action=req.getParameter("action");
try {
// 获取action业务鉴别字符串,获取相应的业务 方法反射对象
Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
// System.out.println(method);
// 调用目标业务 方法
method.invoke(this, req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
2)编写对应的处理类,该类继承了上面的baseServlet,目的就是一个具有相同类型的Servlet,可以使用不同的方法处理不同的业务,进而不用多次写不同的Servlet。(例如:图书的功能:添加图书,修改图书,删除图书… 此时我们至需要写一个BookServlet,在BookServlet编写添加,修改,删除的方法,而怎样确定一个请求是修改图书找到对应的修改方法而不是其他方法呢?这就要用到反射机制,要求我们的方法名必须与请求过来传递的标识参数名称一致。如这儿的page方法,就对应于 String action=req.getParameter(“action”);)
代码如下(示例):
public class OrderTableServlet extends baseServlet {
private OrderTableService orderTableService= new OrderTableServiceImpl();
protected void page(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1、获取请求的参数pageNo 和pageSize
int pageNo= WebUtils.parseInt(request.getParameter("pageNo"), 1);
int pageSize= WebUtils.parseInt(request.getParameter("pageSize"), Page.PAGE_SIZE);
//2、OrderTableServlet.page(pageNo,pageSize)
Page page= orderTableService.page(pageNo,pageSize);
page.setUrl("/orderTableServlet.do?action=page");
//3、保存Page对象到request域中
request.setAttribute("page",page);
//4、请求转发
request.getRequestDispatcher("/back/admin/ordertable_list.jsp").forward(request,response);
}
}
2.Service层(业务层)
1)这里是分页模型的重点和难点,说它难其实也不至于,无非就是一个公式的计算。0 ,总页数=总记录数/每页数量 + 1,如果总记录数%每页数量 ==0(刚好够均分,总页数=总记录数/每页数量 。 而每页的开始页码是多少,这又是一个困惑的人,下面给出公式:每页开始显示的记录 = (当前页码 - 1) * 每页显示的数量; " />
以上图片借鉴与尚硅谷王振国老师的课堂笔记。分析可知,难点在于获取总的页码数和每页应该显示的内容。这里需要注意的是:总记录数/每页显示的数量 如果不能整除,则页数要多加1页。即:总记录数%每页数量>0 ,总页数=总记录数/每页数量 + 1,如果总记录数%每页数量 ==0(刚好够均分,总页数=总记录数/每页数量 。 而每页的开始页码是多少,这又是一个困惑的人,下面给出公式:每页开始显示的记录 = (当前页码 - 1) * 每页显示的数量;
分页的业务层代码如下(示例):
public Page3.Dao层(持久层)page(int pageNo, int pageSize) { Page page = new Page (); // 设置每页显示的数量 page.setPageSize(pageSize); // 求总记录数 Integer pageTotalCount = orderTableDao.queryForPageTotalCount(); // 设置总记录数 page.setPageTotalCount(pageTotalCount); // 求总页码 Integer pageTotal = pageTotalCount / pageSize; if (pageTotalCount % pageSize > 0) { pageTotal+=1; } // 设置总页码 page.setPageTotal(pageTotal); // 设置当前页码 page.setPageNo(pageNo); // 求当前页数据的开始索引 int begin = (page.getPageNo() - 1) * pageSize; // 求当前页数据 List items = orderTableDao.queryForPageItems(begin,pageSize); // 设置当前页数据 page.setItems(items); return page; }
需要指出的是:在SQLServer 和 Mysql 的分页查询他们的语法有点区别;常见的是:
1)SQLServer的分页:
set statistics time on; -- 分页查询(通用型) select top pageSize * from (select row_number() over(order by sno asc) as rownumber,* from student) temp_row where rownumber>((pageIndex-1)*pageSize); set statistics time on; -- 分页查询第2页,每页有10条记录 select top 10 * from (select row_number() over(order by sno asc) as rownumber,* from student) temp_row where rownumber>10;
2)Mysql 的分页:
代码如下(示例):
select * from 表名 order by 属性 desclimit m,n; select * from dept order by deptno desc limit 3,3;
这里引用别人关于两种分页的多种方法【SQL server分页的四种方法和Mysql数据库分页查询讨论专题】,感兴趣的可以看看:
https://blog.csdn.net/weixin_37610397/article/details/80892426
https://blog.csdn.net/bandaoyu/article/details/89844673
代码如下(示例):这里我封装了数据库,用的是阿里巴巴的【commons-dbutils-1.6.jar】这个包。
public abstract class baseDao {
//使用DbUtils操作数据库
private QueryRunner queryRunner = new QueryRunner();
public int update(String sql, Object... args) {
Connection connection = JdbcUtils.getConnection();
try {
return queryRunner.update(connection, sql, args);
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.close(connection);
}
return -1;
}
public T queryForOne(Class type, String sql, Object... args) {
Connection con = JdbcUtils.getConnection();
try {
return queryRunner.query(con, sql, new BeanHandler(type), args);
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.close(con);
}
return null;
}
public List queryForList(Class type, String sql, Object... args) {
Connection con = JdbcUtils.getConnection();
try {
return queryRunner.query(con, sql, new BeanListHandler(type), args);
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.close(con);
}
return null;
}
public Object queryForSinglevalue(String sql, Object... args){
Connection conn = JdbcUtils.getConnection();
try {
return queryRunner.query(conn, sql, new ScalarHandler(), args);
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtils.close(conn);
}
return null;
}
}
public class OrderTableDaoImpl extends baseDao implements OrderTableDao {
@Override
public Integer queryForPageTotalCount() {
String sql="select count(*) from ordertable";
Number count=(Number)queryForSinglevalue(sql);
return count.intValue();
}
@Override
public List queryForPageItems(int begin, int pageSize) {
String sql="select top 4 orderid,number,kid,chanchenpengid,orderdate n" +
"from (select row_number() n" +
"over(order by orderid asc) as rownumber,* n" +
"from ordertable) temp_rown" +
"where rownumber>?";
String sql2="select top "+pageSize+"orderid,number,kid,chanchenpengid,orderdate n" +
"from (select row_number() n" +
"over(order by orderid asc) as rownumber,* n" +
"from ordertable) temp_rown" +
"where rownumber>"+begin;
String sql3="select orderid,number,kid,chanchenpengid,orderdate " +
"from ordertable where kid >"+begin;
return queryForList(OrderTable.class,sql2);
}
}
4.数据展示
通过Web层的 request.setAttribute(“page”,page);我们将查询出来的分页对象存放在Request域中,在前端就可以通过 ${requestScope.page.属性l} 【eg: ${requestScope.page.pageTotal} 】 获取对应的属性。
代码如下(示例):
| 订单id | 数量 | 客户id | 产品代码 | 产品单位 | 下单时间 | 操作 | |
|---|---|---|---|---|---|---|---|
| ${ordertable.orderid} | ${ordertable.number} | ${ordertable.kid} | ${ordertable.chanchenpengid} | ${ordertable.chanpindanwei} |
|
编辑
<%-- |
分页数据的展示代码臃肿,如果在要用的地方都这样写的话,一是麻烦重复,二是代码不简洁。因此我们抽取出来分页的显示代码,要在使用分页功能的地方,通过静态包含的方式引入。
例如:
<%--静态包含页脚内容--%> <%@include file="/pages/common/page_nav.jsp"%>
三、总结 分页功能是个很常见的模块,对于写业务程序员想必是必须会分页的 对于平常很少练习的学生来说,独立的编写程序,的确有点困难。但大多数学生都是跟着视频敲代码,又缺乏思考,盲目的做个机器,当然我也是这样的。因此,要想真正的掌握并且培养独立思考的能力,就要有目的的练习和勤于思考的习惯。



