今天繼續跟大家說說一些非常基礎的東西,這次我們說說分頁查詢。說到分頁,可能很多人都聽說過什麼真分頁、假分頁的。簡單解釋一下,拿第二頁,每頁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是子查詢的列還是主查詢的列。
好了,今天就說到這裡吧,其他的留著以後慢慢說。