Oracle分页
自己的练习:
/*****普通的查询(30数据)****/ select * from ENVIRONMENT_APPLY_AUDIT; /*******查询带行号的数据**/ select ROWNUM ru,AAA.* from ( select * from ENVIRONMENT_APPLY_AUDIT ) AAA; /*******查询第一页 每页5条数据***/ select * from (select AAA.*,ROWNUM ru from (select * from ENVIRONMENT_APPLY_AUDIT ) AAA where ROWNUM<6); select * from (select ROWNUM ru,AAA.* from (select * from ENVIRONMENT_APPLY_AUDIT ) AAA where ROWNUM<6) where ru>0; /**********查询第二页数据********************/ select * from (select ROWNUM ru,AAA.* from (select * from ENVIRONMENT_APPLY_AUDIT ) AAA where ROWNUM<11) where ru>5; /**********查询第三页数据********************/ select * from (select ROWNUM ru,AAA.* from (select * from ENVIRONMENT_APPLY_AUDIT ) AAA where ROWNUM<16) where ru>10;
为什么基于ROWNUM的oracle分页实现,要采用三层嵌套的方式?
1. 首先,在没有order by clause的情况下,oracle的查询结果的顺序会是不确定的
2. 其次,在order by 和 ROWNUM同时使用时,oracle默认的策略是先为伪列rownum赋值,再order by。
3. 再次,因为rownum不可使用 >(=) 来判断的原因,所以需要最外围的第三层嵌套
查询分页就是在原来语句的查询条件上加上根据行号分页的条件,注意与mysql不同的是oracle是从1开始。假设页大小都是5:
mysql分页计算:
页号 | 起始索引 | 取几个 |
1 | 0 | 5 |
2 | 5 | 5 |
计算第一页:limit 0,5
第二页: limit 5,5
规律: limit (pageNum-1)*pageSize,pageSize
Oracle计算分页:
页号 | 起始行号 | 最大行号 |
1 | 1 | 5 |
2 | 6 | 10 |
计算第一页:ROWNUM<=5) where ru>0;
第二页:ROWNUM<=10) where ru>5;
规律:ROWNUM<=pageSize*pageNum)where ru>(pageNum-1)*pageSize;
mybatis利用oracle进行分页就是在上面原始语句的基础上包装两层之后进行分页查询:
例如一个原生的java分页Oracle:
package daoImpl; import java.math.BigDecimal; import java.sql.SQLException; import java.util.List; import javax.sql.DataSource; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import org.junit.Test; import bean.Emp; import dao.Empdao; import utils.DataSourceUtils; /** * 员工管理模块 * @author: qlq * @date : 2017年7月14日上午9:59:51 * @description:Empdao的实现类 */ public class EmpDaoImpl implements Empdao { /** * 获取总的记录数 */ @SuppressWarnings("unchecked") @Override public int findAllRecord() throws Exception { QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource()); String sql = "SELECT COUNT(ID) FROM EMP"; @SuppressWarnings({ "unused", "rawtypes" }) BigDecimal bg = qr.query(sql, new ScalarHandler()); return bg.intValue(); } /** * 获取分页记录 */ @Override public List<Emp> findAllRecord(int start, int end) throws Exception { QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource()); String sql = " select xx.id,xx.name,xx.hiredate "+ " from (select rownum xid,emp.* from emp where rownum<?) xx where xid>?"; Object[] paras={end,start}; return qr.query(sql, new BeanListHandler<Emp>(Emp.class), paras); } @Test public void test1() throws SQLException{ EmpDaoImpl eDaoImpl = new EmpDaoImpl(); try { System.out.println("共有"+eDaoImpl.findAllRecord()+"条记录"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("取第2页数据------------------"); try { System.out.println(eDaoImpl.findAllRecord(5, 11)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
ibatis进行分页的通用(isParameterPresent标签是通用的,可以放在任何需要进行分页查询的sql中)查询:(每次分页都是传一个pagination参数为true(传入起始和结束为止),然后在原来的查询条件上进行两次包装即可完成分页)
<select id="ibatorgenerated_selectByExample" resultMap="ibatorgenerated_BaseResultMap" parameterClass="com.tyust.bean.en.EnApplyInfoExample" > <!-- WARNING - This element is automatically generated by Apache iBATIS ibator, do not modify. --> <isParameterPresent> <isEqual property="pagination" compareValue="true"> <![CDATA[SELECT * FROM ( SELECT A.*, ROWNUM RN FROM ( ]]> </isEqual> </isParameterPresent> select ENVIRONMENT_APPLY_ID, ENVIRONMENT_APPLY_UNIT_ID, ENVIRONMENT_APPLY_USER_ID, ENVIRONMENT_APPLY_TEL, ENVIRONMENT_APPLY_STATUS, ENVIRONMENT_APPLY_DATE, ENVIRONMENT_APPLY_OPINION, ENVIRONMENT_APPLY_SAMPLY, ENVIRONMENT_APPLY_PRODUCTION, ENVIRONMENT_APPLY_USER_NAME from ENVIRONMENT_APPLY_INFO <isParameterPresent > <include refid="ENVIRONMENT_APPLY_INFO.ibatorgenerated_Example_Where_Clause" /> <isNotNull property="orderByClause" > order by $orderByClause$ </isNotNull> </isParameterPresent> <isParameterPresent> <isEqual property="pagination" compareValue="true"> <![CDATA[ ) A WHERE ROWNUM <=#limit# ) WHERE RN >#start# ]]> </isEqual> </isParameterPresent> </select>
1. 首先,在没有order by clause的情况下,oracle的查询结果的顺序会是不确定的2. 其次,在order by 和 ROWNUM同时使用时,oracle默认的策略是先为伪列rownum赋值,再order by。3. 再次,因为rownum不可使用 >(=) 来判断的原因,所以需要最外围的第三层嵌套