今天继续跟大家说说一些非常基础的东西,这次我们说说分页查询。说到分页,可能很多人都听说过什么真分页、假分页的。简单解释一下,拿第二页,每页20条为例:真分:数据库里取 的就是21-40条;假分:数据库取出所有的,然后显示21-40。今天我们要说的就是所谓的真分页。

 

下面是分页查询的核心代码:

/**
* 分页查询
* @param pageNo 第几页
* @param pageSize 每页多少条数据
* @return pageModel
*/
public PageModel findUserList(int pageNo, int pageSize) {
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;
PageModel pageModel = null;
try {
conn = DbUtil.getConnection();
pstmt = conn.prepareStatement(sbSql.toString());
pstmt.setInt(1, pageNo * pageSize);
pstmt.setInt(2, (pageNo - 1) * pageSize);
rs = pstmt.executeQuery();
List userList = new ArrayList();
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 = new PageModel();
pageModel.setList(userList);
pageModel.setTotalRecords(getTotalRecords(conn));
pageModel.setPageSize(pageSize);
pageModel.setPageNo(pageNo);
}catch(SQLException e) {
e.printStackTrace();
}finally {
DbUtil.close(rs);
DbUtil.close(pstmt);
DbUtil.close(conn);
}
return pageModel;
}

/**
* 取得总记录数
* @param conn
* @return
*/
private int getTotalRecords(Connection conn)
throws SQLException {
String sql = "select count(*) from t_user where user_id <> 'root'";
PreparedStatement pstmt = null;
ResultSet rs = null;
int count = 0;
try {
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
rs.next();
count = rs.getInt(1);
}finally {
DbUtil.close(rs);
DbUtil.close(pstmt);
}
return count;
}

 

基本思路就是通过rownum控制查询的记录,想要了解更多关于rownum的信息请用力戳​​解析oracle的rownum​​。

 

下面是一个分页信息的实体类,将分页信息封装了一下:

import java.util.List;

/**
* 封装分页信息
* @author Administrator
*
*/
public class PageModel {

//结果集
private List list;

//查询记录数
private int totalRecords;

//每页多少条数据
private int pageSize;

//第几页
private int pageNo;

/**
* 总页数
* @return
*/
public int getTotalPages() {
return (totalRecords + pageSize - 1) / pageSize;
}

/**
* 取得首页
* @return
*/
public int getTopPageNo() {
return 1;
}

/**
* 上一页
* @return
*/
public int getPreviousPageNo() {
if (pageNo <= 1) {
return 1;
}
return pageNo - 1;
}

/**
* 下一页
* @return
*/
public int getNextPageNo() {
if (pageNo >= getBottomPageNo()) {
return getBottomPageNo();
}
return pageNo + 1;
}

/**
* 取得尾页
* @return
*/
public int getBottomPageNo() {
return getTotalPages();
}

public List getList() {
return list;
}

public void setList(List 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;
}
}

 

最后有几点需要注意:Oracle 认为rownum对于rownum<n((n>1的自然数)的条件认为是成立的,可以找到记录。但是认为rownum> n(n>1的自然数)这种条件不成立,所以查不到记录。想要查找某条记录以后的记录可以用子查询的方式解决,注意子查询中的rownum必须要有别名,否则还是不会查出记录来,这是因为rownum不是某个表的列,如果不起别名的话,无法知道rownum是子查询的列还是主查询的列。

 

 

好了,今天就说到这里吧,其他的留着以后慢慢说。