链接地址:
孔子说的真对,逝者如斯夫,不知不觉七月就又要过去了,上个月的这时候自己还在做着类似DBA的工作,这时候可已经Android入门了,跨度太大,容易 闪了腰,及时总结很重要,今天在看Oracle存储过程的时候,想起来以前使用JDBC和存储过程进行Oracle数据库分页查询的一个例子,这里顺手总 结一下。
首先, 我们需要在Oracle数据库写存储过程,接收三个参数:一个sql语句,一个页码,一个每页条数;返回结果:总页数和当前页Result,如下:
CREATE OR REPLACE PROCEDURE P_Pagination_Util(--存储过程分页工具 sqlString VARCHAR2,--查询语句 page int,--第几页 perPageCount int,--每页几条记录 totalPage out SYS_REFCURSOR,--查询出的总页数 pageResultSet out SYS_REFCURSOR--当前页查询出来的结果集)AS pageSql varchar(2000);--查询某页结果的SQL语句BEGIN open totalPage for 'select count(1) total from ('||sqlString||')';--查询出总数 pageSql := 'select * from (select rownum rn,t.* from ('||sqlString||') t where rownum<='||(page*perPageCount)||') where rn > '||(page-1)||'*'||perPageCount; open pageResultSet for pageSql;END P_Pagination_Util;
做过开发的都知道,分页查询的使用非常的频繁,任何的分页组件都由三个重要参数组成:页码、每页条数和总记录数,其他的比如总页数和下一页、尾页等的页码都可以通过这三个参数计算得到,这里封装一个自己常用的一个分页Bean,类似谷歌分页,也是大神写的,如下:
package jdbc; import java.util.List; @SuppressWarnings("all")public class PageGoogle { private int rowCount;// 数据库一共有多少行 private int navCount;// 计算出一共有多少页 private int pageSize;// 每页多少条 private int next;// 下一页 private int prev;// 上一页 private int begin;// 导航起始 private int end;// 导航结束 private int num;// 当前页 private int first = 1;// 第一页 private int last;// 最后一页 private int navNum = 1;// 有多少个导航 private List pageData;// 用于存放分页之后的数据 public PageGoogle() { };// 无参构造函数 // 构造函数,分页中最关键的三个属性(当前页、总记录数、每页数) public PageGoogle(int num, int rowCount, int pageSize) { this.rowCount = rowCount; this.pageSize = pageSize; this.navCount = (int) Math.ceil(this.rowCount * 1.0 / pageSize); this.last = this.navCount; // 限制当前页范围 this.num = Math.max(this.first, num); this.num = Math.min(this.last, this.num); this.next = Math.min(this.last, this.num + 1);// 计算下一页 this.prev = Math.max(this.first, this.num - 1);// 计算上一页 this.begin = Math.max(this.num - navNum / 2, this.first); this.end = Math.min(this.begin + this.navNum - 1, this.last); if (end - begin < 9) { begin = Math.max(this.first, this.end - this.navNum + 1); } } Getter and Setters... }
有了分页对象,接下来就是在DAO层进行调用和结果集的封装了,如下:
package jdbc; import java.sql.CallableStatement;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.List; public class PaginationProcedure { /** * 分页查询数据 * @param sql * @param currentPage 当前页 * @param pageSize 每页条数 * @return */ public PageGoogle findList4Page(String sql, int currentPage, int pageSize) { String url = "jdbc:oracle:thin:@localhost:1521:orcl"; String user = "test"; String password = "test"; Connection conn = null;// 数据库连接对象 CallableStatement cs = null;// 存储过程对象 ResultSet rs = null;// 结果集,返回分页后的数据 ResultSet rs2 = null;// 结果集,返回查询的总行数 Object object = null;// 需要放入list的对象 PageGoogle page = null;// 分页对象 int total = 0;// 记录总数 int pagenum = 0;// 总页数 List
总结:在软件开发过程中, 我们经常需要分页展示数据,当然一些ORM框架都已经做了很好的封装, 但有时候正是这些封装使分页查询效率低下,这时如果在数据库使用存储过程,并使用原始的JDBC来处理数据库来分页获取数据,可能效率会提升好多,同时也 有助于我们去理解ORM框架的精髓。