* 开始之前 |
做cs项目的时候,记得不是很清楚了,我们是用的控件DataGrid跟表直接进行绑定,优点:配置化,缺点:表结构一旦发生变化就需要配置。BS的项目,由于数据不是很多,自己写页面的时候也没有进行分页。(不排除有这样的控件,jqgrid就很好)之前在SSH中,我们也接触到了分页,和今天说的分页的内容很相似,当时也没有总结一下。
如何让分页可以复用,我们要从分页的功能来看。分页应该具有的是:每页显示的内容,总页数,当前页数,翻页。从这里我们可以捕捉到两个关键性的内容就是页和size。从这两个角度出发,我们开始构建。
* PageModel |
实现复用需要一套翻页的模板,于是就有了PageModel;同时这套模板我们不仅可以用来查询生产的信息,还可以用来查询物料的信息,于是呢?这里应该有什么呢?这里需要用到泛型。我想这样的话,我们构建PageModel的思路就有了。下面是code:
/**
* 分页配置模型
* Created by Viola on 2018/5/27.
*/
public class PageModel<T> {
/**结果集*/
private List<T> list;
/**查询记录数*/
private int totalRecords;
/**每页显示的条数*/
private int pageSize;
/**第几页*/
private int pageNo;
/**返回总页数*/
public int getTotalPages(){
return (totalRecords+pageSize-1)/pageSize;
}
/**
* 取得上一页
* @return
*/
public int getPreviousPageNo(){
if (pageNo<=1){
return 1;
}
return pageNo-1;
}
/**
* 取得下一页
* @return
*/
public int getNextPageNo(){
if (pageNo>=getTotalPages()){
return getTotalPages();
}
return pageNo+1;
}
/**
* 取得首页
* @return
*/
public int getTopPageNo(){
return 1;
}
/**
* 取得尾页
* @return
*/
public int getBottomPageNo(){
return getTotalPages();
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
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;
}
* sql分析 |
接下来,我们就要分析一下sql是怎么执行的了~对于表的操作,便是查询的一个范围,他们不关心分页的事情,对于sql而言是查询的一个范围,几条到几条之间的内容:
下面两段查询几乎一模一样,由于涉及到一个范围,我们需要查一下ROWNUM,于是就有了3层循环,第一个查询字段不是很明确,第二个比较明确一些;
SELECT *
from
(SELECT *
FROM
(select
ROWNUM rn,user_id,USER_NAME,EMAIL,CONTACT_TEL
from
T_USER)
WHERE
rn<=3)
WHERE
rn>=2
select
user_id,USER_NAME,EMAIL,CONTACT_TEL
FROM
(select
ROWNUM rn ,user_id,USER_NAME,EMAIL,CONTACT_TEL
FROM
(select
user_id,USER_NAME,EMAIL,CONTACT_TEL
FROM
T_USER)
WHERE
ROWNUM<=3)
WHERE
rn>=2
忍不住充当一下老师,自己当时也想过这个问题,第二段sql语句中两处rownum,为啥必须要这样使用呢?都用rn可以吗?我想如果你动过手,应该就明白了。
* 整合 |
能够将sql和pageModel结合起来的两个关键的地方是泛型和查询条件;对于sql而言的范围,可以用页号和pagesize确定下来,我认为明白这些原理,开发起来就很easy了~
/**
*分页查询--viola--2018年5月27日21:58:45
* @param pageNo 第几页
* @param pageSize 每页显示的条数
* @return
*/
public PageModel<User> findUserList(int pageNo, int pageSize){
//问号的占位符
StringBuffer sbSql=new StringBuffer();
sbSql.append("select user_id,user_name,password,contact_tel,email,create_date");
sbSql.append(" from");
sbSql.append("(");
sbSql.append("SELECT ROWNUM rn,user_id,user_name,password,contact_tel,email,create_date");
sbSql.append(" from");
sbSql.append("(");
sbSql.append(" select user_id,user_name,password,contact_tel,email,create_date from T_USER where user_id <> 'root' ORDER BY USER_ID");
sbSql.append(") where ROWNUM <= ?");
sbSql.append(")where rn >= ?");
Connection conn=null;
PreparedStatement pstmt=null;
//结果集
ResultSet rs=null;
PageModel<User> pageModel=null;
try {
//建立连接及执行语句
conn=DbUtil.getConnection();
pstmt=conn.prepareStatement(sbSql.toString());
//选取序号之间的数据
pstmt.setInt(1,pageNo*pageSize);
pstmt.setInt(2,(pageNo-1)*pageSize);
List<User> userList=new ArrayList<User>();
rs=pstmt.executeQuery();
while(rs.next()){
User user=new 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的list属性
pageModel=new PageModel<User>();
//集合
pageModel.setList(userList);
//总记录数
pageModel.setTotalRecords(getTotalRecords(conn));
//每页大小
pageModel.setPageSize(2);
//当前第几页
pageModel.setPageNo(pageNo);
}catch (SQLException e){
e.printStackTrace();
}finally {
DbUtil.close(rs);
DbUtil.close(pstmt);
DbUtil.close(conn);
}
return pageModel;
}
* END |
时间过得好快,今天的分页的内容就介绍完毕了,自己的感受是学习跟读书一样是一个由多变少的过程,这其中最少不了的就是思考。
感谢您宝贵的阅读时间,近期项目比较急,没有及时更;万分感谢您的阅读。