j2ee model1模型完成分页逻辑的实现 详解!
在显示用户全部信息的页面,在显示全部数据的时候,长长的滚动条,像是没有边界的天空一样, 让用户查看数据很不方便. 于是, 我们要把这些数据分页显示, 就像office的word一样,每页显示一定数量的数据,这样方便用户观看, 让用户不会产生视觉疲劳, 所以我们在做项目时也把大量的用户数据进行分页显示.
首先说说分页的逻辑.
用户发出查询全部信息的请求(点击菜单信息中的查询按钮)---执行用户的请求----返回执行的结果,并在界面分页显示. 可以看出这和一般的显示数据大致相似, 我们要的是进一步把要显示的数据分页显示出来就ok了.
如果没有前人的分页要让我们自己来创造一个分页的方法来,我会这样想:
1 数据显示, 从数据库中取出自己要的数据放到java的一个集合对象中, 再想法设法的把显示的内容以分页的形式显示.(让客户端来做分页这件事情)
2 界面可以以表格的形式显示, 给表格添加一些分页需要的按钮,例如'第几页' '共几页'等内容,只需要读取一下显示就可以了. 我们把分页这个逻辑放到了数据库来做,让数据库来执行这样的事情.
3 界面只管显示,分页的逻辑让jsp 和控制层同时分担, 让数据库做简单的查询.
实际上,通过我们的经验得知, 在VS中有控件按钮,例如datagrid控件 datatable控件等等而在我们的java中是没有datagrid类似控件的,我们可以用table来做.
我们这的例子用的就是第三种方式, 让服务器和数据库承担相应的分页责任, 而客户端用来显示内容的,这样会让职责更加明确,让系统的扩展性更好.
我们详细说说这个分页的业务逻辑:
我们采用的java model1模型(关于这个模式以后会详细和mvc讲),
model1原型:
我们的分页业务逻辑:
从首先是从界面上(.jsp界面)获取第一页和共几页的参数, 让jsp和后台的执行逻辑类打交道,通过UserManager类的一个方法,在这个方法中传递我们的sql语句,在数据库中进行查询, 查询完毕后返回给我们的jsp页面,在jsp页面中与table绑定.
从数据库中查询,数据库查询的sql语句:
1 首先我们取出除了root用户外的其他用户,并且根据用户id进行排序:
select * from t_user where user_id <> 'root' order by user_id;
2 在上面查询的结果基础上,我们查询他们每一行的编号. 我们用rownum这个字段, 这个字段是oracle自带 的, 类似于我们类的一个属性的样子, rownum表示的第几行代表的就是数字几. 下面我们选取每行的数字,同时选取数据.
select rownum rn,user_id,user_name,password,contact_tel,email,create_date
from
(
select * from t_user where user_id <> 'root' order by user_id
)
我们会看到下面的结果:
其次我们再在上面的基础上进行查询:
select rownum rn,user_id,user_name,password,contact_tel,email,create_date
from
(
select * from t_user where user_id <> 'root' order by user_id
) where rownum<= 2
在上述结果集中我们再进行嵌套查询,为了我们得到的数据正好和一页的 条数 和第几页相吻合, 所以在上面查询出来的基础上嵌套查询:
select user_id,user_name,password,contact_tel,email,create_date
from(
select rownum rn,user_id,user_name,password,contact_tel,email,create_date
from
(
select * from t_user where user_id <> 'root' order by user_id
) where rownum<= 2
)where rn >0
这样我们就可以查询出数据库中总记录的第多少条记录到第多少条记录了.
从分页的业务逻辑中我们可以看从数据库中查询出来,我们要返回很多条数据,例如每页的记录信息,显示的总页
数,显示当前第多少页, 上一页,下一页等, 所以我们把他们进行封装,封装成一个pageModel工具类,这样我们在传递
和返回这些数据,可以把某些数据当做pageModel的一个属性来操作.
我们的pageModel类:
package com.bjpowernode.drp.util; import java.util.List; /**
* 封装分页信息
* @author summer
*
*/
public class PageModel<E> { //设置本类为PageModel的目的是为了,以后用户查询调用分页,其他的也可以调用分页.
//结果集对象.
private List<E> list; // 得到对象.
public List<E> getList() {
return list;
}
//设置对象.
public void setList(List<E> list) {
this.list = list;
}
//查询记录数.
private int totalRecords; //每页多少条数据.
private int pageSize;
//第几页.
private int pageNo; //得到总页数的方法.
public int getTotalPages()
{
return (totalRecords+pageSize-1)/pageSize ;
} //取得首页.
public int getPageTopNo()
{
return 1;
} //取得尾页,总的页数,尾页第总的位数页.
public int getBottomPageNo()
{
return getTotalPages();
} //取得上一页的页号.
public int getPreviousPageNo()
{
//判断当前页是否是最后一页或者第一页
if(pageNo <= 1)
{
return 1;
} //拿到当前页.再减去一.
return pageNo -1; } //取得下一页面.
public int getNextPageNo()
{
if(pageNo >= getBottomPageNo() )
{
return getBottomPageNo();
} return pageNo + 1; } //得到总记录数.
public int getTotalRecords() {
return totalRecords;
}
//设置总记录数.
public void setTotalRecords(int totalRecords) {
this.totalRecords = totalRecords;
}
//得到页面的大小.
public int getPageSize() {
return pageSize;
}
//设置页面的大小.
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
//得到第多少页面.
public int getPageNo() {
return pageNo;
}
//设置第多少页面.
public void setPageNo(int pageNo) {
this.pageNo = pageNo;
} }
在这里面我们在定义对象的集合用的是泛型, 为什么是使用泛型?
//结果集对象 private List<E> list;
什么是泛型?
泛型是一种特殊的类型,它把指定类型的工作推迟到客户端代码声明并实例化类或方法的时候进行.
因为我们在定义一个对象的集合的时候,我们通常不确定对象的类型,所以我们用这样的泛型:private List<E> list;而且我们的分页需求也不止一个界面,为了能把分页类更好的封装,我们采取泛型,这样更加灵
活. 并且泛型能让我们提前发现错误,我们首先约定一个集合,这个集合中什么类型的对象都可以放,一次只要放同
一种类型的对象就ok.就像水果篮儿一样,这个水果篮可以放香蕉,可以放草莓,但不能混放.
为了让界面最少的逻辑,或者说没有逻辑,我们把更多的信息封装在了这个pageModel类中,并且在这个类中执行了
一些简单的方法,例如,得到查询的总页数:
public int getTotalPages(){
return (totalRecords+pageSize-1)/pageSize ; }
得到上一页,得到下一页等方法.
下面看我们的jsp页面, jsp页面除了需要显示信息外,也有些许的控制逻辑,也就是和后台打交道的代码.:
我们用table进行控制的:
<table width="95%" border="1" cellspacing="0" cellpadding="0"
align="center" class="table1">
<tr>
<td width="55" class="rd6">
<input type="checkbox" name="ifAll" onClick="checkAll(this)">
</td>
<td width="119" class="rd6">
用户代码
</td>
<td width="152" class="rd6">
用户名称
</td>
<td width="166" class="rd6">
联系电话
</td>
<td width="150" class="rd6">
</td>
<td width="153" class="rd6">
创建日期
</td>
</tr>
<%
List<User> userList = pageModel.getList();
for (Iterator<User> iter=userList.iterator(); iter.hasNext();) {
//用泛型之后就不需要转换类型了.
User user = iter.next();
%>
<tr>
<td class="rd8">
<input type="checkbox" name="selectFlag" class="checkbox1"
value="<%=user.getUserId() %>">
</td>
<td class="rd8">
<%=user.getUserId() %>
</td>
<td class="rd8">
<%=user.getUserName() %>
</td>
<td class="rd8">
<%=user.getContactTel() %>
</td>
<td class="rd8">
<%=user.getEmail() %>
</td>
<td class="rd8">
<%=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(user.getCreateDate()) %>
</td>
</tr>
<%
}
%>
</table>
我们在循环显示User集合中的内容时,使用了java迭代器 Iterator, 迭代器是一个对象, 它可以遍历并选择序列
中的对象, 而开发人员不需要了解该序列的底层结构. 迭代器通常被称为"轻量级" 对象, 因为创建它的代价小.
在这里就不详细解说了.
List<User> userList = pageModel.getList();
for (Iterator<User> iter=userList.iterator(); iter.hasNext();)
{
//用泛型之后就不需要转换类型了.
User user = iter.next(); }
在执行首页,上一页,下一页的时候我们用的是js来进行控制的:
//首页.
function topPage() {
window.self.location = "user_maint.jsp?pageNo=<%=pageModel.getPageTopNo()%>";
}
//取得上一页.
function previousPage() {
window.self.location = "user_maint.jsp?pageNo=<%=pageModel.getPreviousPageNo()%>";
}
//取得下一页的.
function nextPage() {
window.self.location = "user_maint.jsp?pageNo=<%=pageModel.getNextPageNo()%>";
}
在jsp中:
<%
int pageNo = 1;
int pageSize = 4; String pageNoString = request.getParameter("pageNo");
if (pageNoString != null) {
pageNo = Integer.parseInt(pageNoString);
} PageModel<User> pageModel =UserManager.getInstance().findUserList(pageNo, pageSize);
%>
我们的UserManager类:
传递sql ,与书库打交道查询的代码:
/**
* 分页查询
* @param pageNo 第几页
* @param pageSize 每页多少条数据
* @return pagemode实体.
* @throws ClassNotFoundException
*/
public PageModel<User> findUserList(int pageNo,int pageSize) throws ClassNotFoundException{
//查询的slq语句.
StringBuffer sbSql = new StringBuffer();
sbSql.append("select user_id, user_name, password, contact_tel, email, create_date ")
.append("from ")
.append("( ")
.append("select rownum rn, user_id, user_name, password, contact_tel, email, create_date ")
.append("from ")
.append("( ")
.append("select user_id, user_name, password, contact_tel, email, create_date from t_user where user_id <> 'root' order by user_id ")
.append(") where rownum <= ? ")
.append(") where rn > ? "); //建立连接对象。
Connection conn = null; PreparedStatement pstmt = null;
//结果记录集.
ResultSet rs = null;
//定义user对象.
PageModel<User> pageModel = null;
try { conn = DbUtil.getConnection();
pstmt = conn.prepareStatement(sbSql.toString()); //取得值.
pstmt.setInt(1,pageNo * pageSize);
pstmt.setInt(2,(pageNo-1) * pageSize); //传递给res对象.
rs = pstmt.executeQuery(); List<User> userList = new ArrayList();
//拿出来rs中的内容.
while(rs.next())
{ User user = new User();
//从记录集中取出数据库中查询的记录的数据,并给user实体.
user.setUserId(rs.getString("USER_ID"));
user.setUserName(rs.getString("USER_NAME"));
user.setPassword(rs.getString("PASSWORD"));
user.setContactTel(rs.getString("CONTACT_TEL"));
user.setEmail(rs.getString("EMAIL"));
user.setCreateDate(rs.getTimestamp("CREATE_DATE")); userList.add(user);
}
//实例化pagemodel类.
pageModel =new PageModel<User>(); pageModel.setList(userList); //传递当前第几页.
pageModel.setPageNo(pageNo); //总记录数.
pageModel.setTotalRecords(getTotalRecords(conn)); pageModel.setPageSize(pageSize);
} catch (SQLException e) {
// 打印错误.
e.printStackTrace();
}finally{ //关闭.
DbUtil.close(rs);
DbUtil.close(pstmt);
DbUtil.close(conn); } return pageModel;
}
在学习分页技术的时候,以前在vs中也曾经实现过分页逻辑的实现,貌似使用的控件. vs中分页,由于没有总结,所以都忘记的差不都了........这也告诉我学习一定要时常总结,不要相信自己的大脑,我们要相信计算机,相信文字,从感性到理性过渡吧........好记性不如烂笔头(博客)!
从这次分页的学习看来,还是要从大方面的去把握,把握全局,把握这个过程,再从细节上各个的击破,不能不求甚解.尤其是第二次遇到这个东西的时候了.....
昨天的雷声似乎还在耳畔响起,就是再大的雷声,今天的阳光依然明媚,一切如初!
j2ee model1模型完成分页逻辑的实现 详解!的更多相关文章
- 数据挖掘模型中的IV和WOE详解
IV: 某个特征中 某个小分组的 响应比例与未响应比例之差 乘以 响应比例与未响应比例的比值取对数 数据挖掘模型中的IV和WOE详解 http://blog.csdn.net/kevin7658/ar ...
- Linux分页机制之分页机制的实现详解--Linux内存管理(八)
1 linux的分页机制 1.1 四级分页机制 前面我们提到Linux内核仅使用了较少的分段机制,但是却对分页机制的依赖性很强,其使用一种适合32位和64位结构的通用分页模型,该模型使用四级分页机制, ...
- 转载:数据挖掘模型中的IV和WOE详解
1.IV的用途 IV的全称是Information Value,中文意思是信息价值,或者信息量. 我们在用逻辑回归.决策树等模型方法构建分类模型时,经常需要对自变量进行筛选.比如我们有200个候选自变 ...
- 评分卡模型中的IV和WOE详解
1.IV的用途 IV的全称是Information Value,中文意思是信息价值,或者信息量. 我们在用逻辑回归.决策树等模型方法构建分类模型时,经常需要对自变量进行筛选.比如我们有200个候选 ...
- 模型 - 视图 - 控制器(MVC)详解
模型视图控制器(MVC)一个相当实用且十分流行的设计模式.作为一位称职码农,你不可能没听说过吧. 不幸的是它难以让人理解. 在本文中,我将给出我认为是MVC的最简单的解释,以及为什么你应该使用它. 什 ...
- JavaScript学习总结(四)——逻辑OR运算符详解
在JavaScript中,逻辑OR运算符用||表示 1 var bTrue = true; 2 var bFalse = false; 3 var bResult = bTrue || bFalse; ...
- JavaScript学习总结(三)——逻辑And运算符详解
在JavaScript中,逻辑 AND 运算符用双和号(&&)表示 1 var bTrue = true; 2 var bFalse = false; 3 var bResult = ...
- JavaScript学习总结(二)——逻辑Not运算符详解
在JavaScript 中,逻辑NOT运算符与C和Java中的逻辑 NOT 运算符相同,都由感叹号(!)表示.与逻辑 OR 和逻辑 AND 运算符不同的是,逻辑 NOT 运算符返回的一定是 Boole ...
- 微信小程序开发教程(七)逻辑层——.js详解
逻辑层,是事务逻辑处理的地方.对于小程序而言,逻辑层就是.js脚本文件的集合.逻辑层将数据进行处理后发送给视图层,同时接收视图层的事件反馈. 微信小程序开发框架的逻辑层是由JavaScript编写.在 ...
随机推荐
- [flask]flask_login模块,session及其他
读flask源码的时候,有一点一直到现在都没有一个清晰的概念,比如四个全局变量g,current_app,session,request是怎么做到的 按照查到的资料里面的说法,为了不至于每次都主动调用 ...
- 【SQL】185. Department Top Three Salaries
The Employee table holds all employees. Every employee has an Id, and there is also a column for the ...
- Visual Studio 2017强制更新方法
Visual Studio 2017强制更新方法 Visual Studio 2017更新时候,用户都是根据消息提示,进行更新.这样做的好处,就是微软可以分批下发升级包,避免集中更新.不过为了早点 ...
- C语言初始化
注意:为什么要进行C语言环境的初始化?在没有进行C语言环境的初始化之前的初始化工作都是用汇编进行初始化的.比如核心初始化,和内存初始化 栈:栈帧:一个进程中一般会有多个函数,每一个函数都需要在内存中开 ...
- android studio 汉化包 美化包
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 汉化包 百度云盘 下载地址:https://pan.baidu.com/s/1pLjwy ...
- CF893F Subtree Minimum Query 主席树
如果是求和就很好做了... 不是求和也无伤大雅.... 一维太难限制条件了,考虑二维限制 一维$dfs$序,一维$dep$序 询问$(x, k)$对应着在$dfs$上查$[dfn[x], dfn[x] ...
- 在线HTTP速度测试(响应时间测试)及浏览器兼容测试
一.前言 网站的响应时间,是判断一个网站是否是好网站的重要的因素之一.百度首页的响应时间在全国各个省份小于10ms.这个响应时间远远好于竞争对手.根据美丽说的技术负责人分析,美丽说访问速度提升10%, ...
- [CC-MCHEF]MasterChef
[CC-MCHEF]MasterChef 题目大意: \(n(n\le10^5)\)片花,第\(i\)片花的美观度为\(b_i(|b_i|\le10^9)\).总体美观度为各片花的美观度之和. 由于有 ...
- Java并发(二十):线程本地变量ThreadLocal
ThreadLocal是一个本地线程副本变量工具类. 主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不同的 ...
- Mysql的学习随笔day2
关于输入中文的问题,各种更改完utf8后仍然乱码. 最后找到一种可行的方法:在insert之前,输入 set names 'gbk' 约束保证数据的完整性和一致性.约束分为表级约束和列级约束,前者可以 ...