Java Web——分页技术
一、在数据库中存储的数据量特别大时(百万级以上),使用数据库分页技术,将已经分页好的数据存储在集合中返回给用户
1 /** 2 * 查询雇员(根据条件组合查询-数据库分页) 3 * @param emp 4 * @param pageSize 每页显示条数 5 * @param pageNum 当前页码 6 * @return 7 */ 8 public List<Emp> getEmp(Emp emp, int pageSize, int pageNum) { 9 try { 10 11 String sql = "select * from ( select e.empno,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,e.deptno,d.dname,d.loc,m.ename mgrname,rownum rn " 12 + " from emp e,dept d,emp m " 13 + " where e.mgr = m.empno(+) and e.deptno = d.deptno "; 14 15 16 //绑定查询条件---start--------------------------------------------------- 17 //雇员编号 18 int empno= emp.getEmpno(); 19 if(empno > 0) 20 { 21 sql += " and e.empno like '%" + empno +"%' "; 22 } 23 //雇员姓名 24 String ename = emp.getEname(); 25 if(ename != null && !"".equals(ename)) 26 { 27 sql += " and e.ename like '%" + ename +"%' ";//模糊查询 28 } 29 //职位 30 String job = emp.getJob(); 31 if(job != null && !"".equals(job)) 32 { 33 sql += " and e.job = '" + job +"' "; 34 } 35 //部门编号 36 int deptno = emp.getDept().getDeptno(); 37 if(deptno > 0) 38 { 39 sql += " and e.deptno = " + deptno; 40 } 41 //绑定查询条件---end--------------------------------------------------- 42 43 sql += " and rownum <= "+ (pageSize * pageNum) +" ) where rn >= " + ((pageNum-1) * pageSize +1); 44 45 System.out.println(sql); 46 47 stat = conn.prepareStatement(sql); 48 49 rs = stat.executeQuery(); 50 51 List<Emp> empList = new ArrayList<Emp>(); 52 53 while(rs.next()) 54 { 55 Emp temp = new Emp(); 56 temp.setEmpno(rs.getInt("empno")); 57 temp.setEname(rs.getString("ename")); 58 temp.setJob(rs.getString("job")); 59 60 //上级主管(复合属性) 61 Emp mgr = new Emp(); 62 mgr.setEmpno(rs.getInt("mgr")); 63 mgr.setEname(rs.getString("mgrname")); 64 //...... 65 temp.setMgr(mgr); 66 67 temp.setHiredate(rs.getDate("hiredate")); 68 temp.setSalary(rs.getDouble("sal")); 69 temp.setComm(rs.getDouble("comm")); 70 71 //部门(复合属性) 72 Dept dept = new Dept(); 73 dept.setDeptno(rs.getInt("deptno")); 74 dept.setDname(rs.getString("dname")); 75 dept.setLocation(rs.getString("loc")); 76 temp.setDept(dept); 77 78 empList.add(temp); 79 } 80 return empList; 81 82 } catch (SQLException e) { 83 e.printStackTrace(); 84 } 85 return null; 86 } 87 88 }
二、当取得的数据不多时,推荐使用基于结果集的分页技术,这样可以尽量少的访问数据库
(1)建立基于结果集分页的工具类(重要)
1 package Util; 2 3 import java.util.List; 4 5 import model.User; 6 7 public class PageUtil { 8 //总页数 9 private int pageCount; 10 //总行数 11 private int rowCount; 12 //当前页数,默认情况下为1 13 private int pageNum = 1; 14 //每页条数,默认情况下为5 15 private int pageSize = 5; 16 //开始索引(重要) 17 private int beginIndex; 18 //结束索引(重要) 19 private int endIndex; 20 21 //构造函数 22 public PageUtil(List<User> user){ 23 //为总行数赋值 24 this.rowCount = user.size(); 25 //算出总页数,并赋值 26 if(this.rowCount%this.pageSize==0){ 27 this.pageCount = this.rowCount/this.pageSize; 28 }else { 29 this.pageCount = this.rowCount/this.pageSize+1; 30 } 31 setPageNum(this.pageNum); 32 } 33 34 public int getPageCount() { 35 return pageCount; 36 } 37 38 public void setPageCount(int pageCount) { 39 this.pageCount = pageCount; 40 } 41 42 public int getRowCount() { 43 return rowCount; 44 } 45 46 public void setRowCount(int rowCount) { 47 this.rowCount = rowCount; 48 } 49 50 public int getPageNum() { 51 return pageNum; 52 } 53 54 public void setPageNum(int pageNum) { 55 this.pageNum = pageNum; 56 //计算开始索引 57 this.beginIndex = (this.pageNum-1)*this.pageSize; 58 //计算结束索引 59 this.endIndex = this.pageNum*this.pageSize; 60 if(this.endIndex>this.rowCount){ 61 this.endIndex = this.rowCount; 62 } 63 } 64 65 public int getPageSize() { 66 return pageSize; 67 } 68 69 public void setPageSize(int pageSize) { 70 this.pageSize = pageSize; 71 } 72 73 public int getBeginIndex() { 74 return beginIndex; 75 } 76 77 public void setBeginIndex(int beginIndex) { 78 this.beginIndex = beginIndex; 79 } 80 81 public int getEndIndex() { 82 return endIndex; 83 } 84 85 public void setEndIndex(int endIndex) { 86 this.endIndex = endIndex; 87 } 88 89 90 }
(2)dao层中通过方法取得满足条件的所有待选行,通过服务层返回给servlet,在servlet中调用分页工具类,取得开始索引和结束索引,在使用list的sublist方法将选中的候选行返回给用户
1 String pageNum = request.getParameter("pageNum"); 2 HttpSession session = request.getSession(); 3 //当不指定具体是哪一页时 4 if(pageNum==null||"".equals(pageNum)){ 5 //1.取得参数 6 String username = request.getParameter("username"); 7 String sex = request.getParameter("sex"); 8 String cert_type = request.getParameter("cert_type"); 9 String cert = request.getParameter("cert"); 10 String user_type = request.getParameter("user_type"); 11 System.out.println("servlet:"+username); 12 //2.封装进对象 13 User user = new User(); 14 user.setUsername(username); 15 user.setSex(sex); 16 //如果对象需要转化为int,那么为了防止使用Interger.valueof()方法时出现空指针情况,必须先进行判断是否为空 17 if(cert_type != null && !"".equals(cert_type)) 18 { 19 user.setCert_type(Integer.valueOf(cert_type)); 20 } 21 user.setCert(cert); 22 if(user_type != null && !"".equals(user_type)) 23 { 24 user.setUser_type(Integer.valueOf(user_type)); 25 } 26 27 //3.调用服务层方法取得结果集 28 List<User> users = SelectUserService.Instance().getUser(user); 29 //4.对结果集进行分页操作 30 PageUtil pu = new PageUtil(users); 31 List<User> selectUsers = users.subList(pu.getBeginIndex(), pu.getEndIndex()); 32 //结果集存入session中,可以让下次指定页数分页时不用再重新用服务层 33 session.setAttribute("users", users); 34 //分页好的结果存入session中 35 session.setAttribute("selectUsers", selectUsers); 36 //分页信息存入session 37 session.setAttribute("pu", pu);
(3)当用户选中某一页时,取出事先存在session中的全部候选行,在调用存在session中的分页工具类对象,进行指定当前页数,再取得选中行
1 else { 2 //指定某一页时,调用分页工具类修改页面 3 PageUtil pu = (PageUtil) session.getAttribute("pu"); 4 List<User> users = (List<User>) session.getAttribute("users"); 5 pu.setPageNum(Integer.valueOf(pageNum)); 6 List<User> selectUsers = users.subList(pu.getBeginIndex(), pu.getEndIndex()); 7 session.setAttribute("selectUsers", selectUsers); 8 session.setAttribute("pu", pu); 9 10 }