Oracle分页

Oracle分页有许多形式,查询效率有高低之分,现在写其中的一种。

一、分页SQL
注:在创建相关表时字段名不能重复,如t_empl表中有个name,在t_jop中也来个name--这样的话查询会出异常。
SELECT * FROM (
SELECT A.*, ROWNUM RN from (
select e.eid,e.ename,e.sex,to_char(e.birthday,'yyyy-mm-dd'),d.dname,j.jname,to_char(e.hiredate,'yyyy-mm-dd'),js.status, d.did,j.jid,js.jsid from t_empl e,t_dept d,t_job j,t_jobstatus js where e.deptno=d.did and e.job=j.jid and e.status=js.jsid  and e.eid!=42 and j.jname!='董事长' order by eid
) A 
) WHERE RN BETWEEN ? AND ?


二、结合项目
如果在项目中模型层有抽取baseDao,则分页SQL自然会分离,下面是这样情况下的写法。
1.查询员工的SQL。需注意的是:由于这里的查询有可能加条件,所以排序要加在最后(sql.append(" order by eid) A ");)
public Pager<Object[]> search(Empl empl,Job job,Dept dept,JobStatus jobStatus,int currId,int offset) {
		List<Object> params=new ArrayList<>();
		StringBuffer sql=new StringBuffer();
		sql.append("SELECT A.*, ROWNUM RN from (select e.eid,e.ename,e.sex,to_char(e.birthday,'yyyy-mm-dd'),d.dname,j.jname,to_char(e.hiredate,'yyyy-mm-dd'),js.status, d.did,j.jid,js.jsid "
				+ "from t_empl e,t_dept d,t_job j,t_jobstatus js "
				+ "where e.deptno=d.did and e.job=j.jid and e.status=js.jsid  and e.eid!="+currId+" and j.jname!='董事长'");
		if(empl!=null){
			if(empl.getEname()!=null&&!"".equals(empl.getEname().trim())){
				sql.append(" and e.ename like ?");
				params.add("%"+empl.getEname()+"%");
			}
		}
		if(job!=null){
			if(job.getJname()!=null&&!"请选择该用户所属职位".equals(job.getJname().trim())){
				sql.append(" and j.jname like ?");
				params.add("%"+job.getJname()+"%");
			}
		}
		if(dept!=null){
			if(dept.getDname()!=null&&!"请选择该用户所属部门".equals(dept.getDname().trim())){
				sql.append(" and d.dname like ?");
				params.add("%"+dept.getDname()+"%");
			}
		}
		if(jobStatus!=null){
			if(jobStatus.getStatus()!=null&&!"请选择该用户所属态".equals(jobStatus.getStatus().trim())){
				sql.append(" and js.status like ?");
				params.add("%"+jobStatus.getStatus()+"%");
			}
		}
		sql.append(" order by eid) A ");
		
		return listAsObjectArrayHaveParam(sql.toString(), offset, 10, params.toArray());
	}

注:实际上这个SQL只是去除了原SQL中最外层的嵌套"SELECT * FROM (..) WHERE RN BETWEEN ? AND ?"
2.baseDao中的SQL
a.查询从行数的sql_count:这里采用StringBuffer装SQL,更加灵活。b.查询数据的sql_select:这里只是把需要的最外层SQL加入就好。
public Pager<Object[]> listAsObjectArrayHaveParam(String sql, int offset, int pageRows,
			Object... args) {
			Connection conn = C3P0DBUtils.getConnection();
			QueryRunner run = new QueryRunner();
			Pager<Object[]> pager = new Pager<Object[]>();
			try {
				// 统计总行数
				/*String sql_count = "select count(*) "
						+ sql.substring(sql.indexOf("from"));*/
				StringBuffer sql_count = new StringBuffer();
				sql_count.append("select count(*) from ("+sql+")");
				BigDecimal sumRows = null;
				if (args == null || args.length == 0) {
					sumRows = run.query(conn, sql_count.toString(),
							new ScalarHandler<BigDecimal>());
				} else {
					sumRows = run.query(conn, sql_count.toString(),
							new ScalarHandler<BigDecimal>(), args);
				}
				// 总页数
				int sumPages = (int) ((Integer.parseInt(String.valueOf(sumRows))
						+ pageRows - 1) / pageRows);
				// 判断当前页
				if (offset > sumPages) { // 大于总页数就等于总页数
					offset = sumPages;
				}
				if (offset < 1) {
					offset = 1;
				}
				// 数据
				List<Object[]> list = null;
				if (args == null || args.length == 0) {
					String sql_select = "SELECT * FROM (" + sql + ") WHERE RN BETWEEN ? AND ?";
					System.out.println(sql_select);
					list = run.query(conn, sql_select, new ArrayListHandler(),
							(offset - 1) * pageRows + 1, (offset - 1) * pageRows
									+ pageRows);
				} else {
					// 数据
					// 直接把页面和查询的行数写在sql后面
					String sql_select = "SELECT * FROM (" + sql + ") WHERE RN BETWEEN "+((offset - 1) * pageRows + 1)+" AND "+(pageRows + (offset - 1) * pageRows)+"";
					list = run.query(conn, sql_select, new ArrayListHandler(), args);
				}
				// 数据封装
				pager.setList(list);
				pager.setOffset(offset);
				pager.setPageRows(pageRows);
				pager.setSumPages(sumPages);
				pager.setSumRows(Integer.parseInt(String.valueOf(sumRows)));
			} catch (SQLException e) {
				e.printStackTrace();
			} finally {
				C3P0DBUtils.close(conn);
			}
			return pager;
		
	}


大功告成!

你可能感兴趣的:(oracle,sql,分页,javaweb)