Oracle 分页存储过程
Posted duosl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle 分页存储过程相关的知识,希望对你有一定的参考价值。
--1、创建一个分页所用的包,定义接收结果集的游标 create or replace package pkg_fy as type cur_records is ref cursor; end pkg_fy; --2、创建一个分页的存储过程, --输入参数: --tableName 需要查询的表名 --searchFieldSQL 需要查询的字段SQL,可以传入* --pageNo 当前页码 --pageSize 每页的记录数 --whereCase 查询所需要的条件 --orderSQL 排序SQL --输出参数: --total 总记录条数 --totalPage 总页数 --resultSet 返回的结果集 --辅助变量: --beginIndex -->查询的开始下标 (pageNo-1)*pageSize --endIndex --> 查询的结束下标 pageNo*pageSize --sql1 获取总记录条数的SQL语句 --sql2 获取要查询的页的记录的SQL语句 -----------------------创建存储过程-------------------------------- create or replace procedure p_fenye( tableName in varchar2, --需要查询的表名 searchFieldSQL in varchar2, --需要查询的字段SQL,可以传入* pageNo in number, --当前页码 pageSize in number, --每页的记录数 whereCase in varchar2, --查询所需要的条件 orderSQL in varchar2, --排序SQL total out number, --总记录条数 totalPage out number, --总页数 resultSet out pkg_fy.cur_records --返回的结果集 ) is beginIndex number; --查询的开始下标 (pageNo-1)*pageSize endIndex number; -- 查询的结束下标 pageNo*pageSize sql1 varchar2(1000); --获取总记录条数的SQL语句 sql2 varchar2(2000); --获取要查询的页的记录的SQL语句 begin --1、获取总记录数,并保存到输出参数中 sql1:=‘select count(*) from ‘||tableName; if whereCase is not null or whereCase <> ‘‘ then sql1:=sql1 || ‘ where ‘|| whereCase; end if; Execute immediate sql1 into total;--立即执行该SQL语句,将结果保存在total变量中 --2、计算该页的起始下标和结束下标以及总页数 beginIndex:=(pageNo-1)*pageSize; endIndex:=pageNo*pageSize; totalPage:=ceil(total/pagesize); --3、拼装查询语句 sql2:=‘select * from (select rownum rn,t1.* from (select ‘|| searchFieldSQL ||‘ from ‘|| tableName; --添加where条件 if whereCase is not null or whereCase <> ‘‘ then sql2:=sql2 || ‘ where ‘|| whereCase; end if; --添加排序 if orderSQL is not null or orderSQL <> ‘‘ then sql2:=sql2 || ‘ ‘ || orderSQL; end if; sql2:=sql2 || ‘) t1 where rownum<=‘|| endIndex ||‘) t2 where rn>‘|| beginIndex; dbms_output.put_line(sql2); --4、将查询结果保存在游标中 open resultSet for sql2; end; -----------------------创建存储过程--------------------------------
Java调用该存储过程
分页的工具实体类
/** * 分页实体类,用来保存查询到的数据,以及总记录数和总页数 * @author Duosl * */ public class FenYeModel { private List<?> list; private Integer total; private Integer totalPage; public List<?> getList() { return list; } public void setList(List<?> list) { this.list = list; } public Integer getTotal() { return total; } public void setTotal(Integer total) { this.total = total; } public Integer getTotalPage() { return totalPage; } public void setTotalPage(Integer totalPage) { this.totalPage = totalPage; } }
分页dao层代码
import java.lang.reflect.Field; import java.math.BigDecimal; 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.Date; import java.util.List; public class FenYeUtil { // 数据库连接信息 private static String DRIVER_CLASS = "oracle.jdbc.driver.OracleDriver"; private static String URL = "jdbc:oracle:thin:localhost:1521/orcl?useEncoding=True&characterEncoding=utf-8"; private static String USERNAME = "scott"; private static String PASSWORD = "tiger"; static Connection conn = null; public static Connection getConnection() { try { Class.forName(DRIVER_CLASS); conn = DriverManager.getConnection(URL, USERNAME, PASSWORD); } catch (Exception e) { throw new RuntimeException("数据库连接出现错误..."); } return conn; } /** * 分页获取表中的数据,返回ResultSet对象 * * @param clz * 需要将查询到的数据转换的类 * @param tableName * 需要查询的表名 * @param searchFieldSQL * 需要查询的字段SQL,可以传入*,例如:username,password * @param pageNo * 当前页码,即要查询的页码 * @param pageSize * 每页的记录数 * @param whereCase * 查询所需要的条件 例如: username=‘zhangsan‘ and password=‘m123‘ * @param orderSQL * 排序SQL 例如: order by username desc * @return 返回一个结果集 * @throws SQLException */ public static ResultSet getRecordsByPage(String tableName, String searchFieldSQL, Integer pageNo, Integer pageSize, String whereCase, String orderSQL) throws SQLException { String sql = "{call p_fenye(?,?,?,?,?,?,?,?,?)}"; conn = getConnection(); CallableStatement cs = conn.prepareCall(sql); cs.setObject(1, tableName); cs.setObject(2, searchFieldSQL); cs.setObject(3, pageNo); cs.setObject(4, pageSize); cs.setObject(5, whereCase); cs.setObject(6, orderSQL); cs.registerOutParameter(7, oracle.jdbc.OracleTypes.NUMBER); cs.registerOutParameter(8, oracle.jdbc.OracleTypes.NUMBER); cs.registerOutParameter(9, oracle.jdbc.OracleTypes.CURSOR); cs.execute(); Integer total=cs.getInt(7); Integer totalPage=cs.getInt(8); ResultSet rs = (ResultSet) cs.getObject(9); System.out.println("总记录数:"+total); System.out.println("总页数:"+totalPage); while (rs.next()) { System.out.print(rs.getObject(1)+" "); System.out.print(rs.getObject(2)+" "); System.out.print(rs.getObject(3)+" "); System.out.print(rs.getObject(4)+" "); System.out.print(rs.getObject(5)+" "); System.out.print(rs.getObject(6)+" "); System.out.println(rs.getObject(7)+" "); } System.out.println(rs); return rs; } /** * 分页获取表中的数据,返回上面定义的实体类对象--FenYeModel * * @param clz * 需要将查询到的数据转换的类 * @param tableName * 需要查询的表名 * @param searchFieldSQL * 需要查询的字段SQL,可以传入*,例如:username,password * @param pageNo * 当前页码,即要查询的页码 * @param pageSize * 每页的记录数 * @param whereCase * 查询所需要的条件 例如: username=‘zhangsan‘ and password=‘m123‘ * @param orderSQL * 排序SQL 例如: order by username desc * @return 返回一个工具类,包含转换后的List、总记录数和总页数 * @throws Exception */ public static FenYeModel getRecordsByPage(Class<?> clz, String tableName, String searchFieldSQL, Integer pageNo, Integer pageSize, String whereCase, String orderSQL) throws Exception { String sql = "{call p_fenye(?,?,?,?,?,?,?,?,?)}"; conn = getConnection(); CallableStatement cs = conn.prepareCall(sql); cs.setObject(1, tableName); cs.setObject(2, searchFieldSQL); cs.setObject(3, pageNo); cs.setObject(4, pageSize); cs.setObject(5, whereCase); cs.setObject(6, orderSQL); cs.registerOutParameter(7, oracle.jdbc.OracleTypes.NUMBER); cs.registerOutParameter(8, oracle.jdbc.OracleTypes.NUMBER); cs.registerOutParameter(9, oracle.jdbc.OracleTypes.CURSOR); cs.execute(); Integer total=cs.getInt(7); Integer totalPage=cs.getInt(8); ResultSet rs = (ResultSet) cs.getObject(9); FenYeModel model=toModelList(clz, rs); model.setTotal(total); model.setTotalPage(totalPage); return model; } /** * 将查询到的结果集和总记录数、总页数封装到实体类中 * * @param clz * 需要将查询到的数据转换的类 * @param ResultSet * 查询到的结果集 * @return * @throws Exception */ private static FenYeModel toModelList(Class<?> clz, ResultSet rs) throws Exception{ FenYeModel model=new FenYeModel(); List<Object> list = new ArrayList<Object>(); Field[] fields = clz.getDeclaredFields(); while (rs.next()) { Object obj = clz.newInstance(); for (Field field : fields) { field.setAccessible(true); try { Object obj2 = null; if (rs.getObject(field.getName()) != null) { if ("java.math.BigDecimal".equals(rs.getObject(field.getName()).getClass().getName())) { if("java.lang.Integer".equals(field.getType().getName())){ obj2 = ((BigDecimal) rs.getObject(field.getName())).intValue(); }else if("java.lang.Double".equals(field.getType().getName())){ obj2 = ((BigDecimal) rs.getObject(field.getName())).doubleValue(); } //此处可以进行其他Number类型的判断和类型转换 }else if("java.sql.Timestamp".equals(rs.getObject(field.getName()).getClass().getName())){ obj2 = (Date)rs.getObject(field.getName()); } else { obj2 = rs.getObject(field.getName()); } field.set(obj, obj2); } } catch (Exception e) { //测试的时候最好加上这句异常,投入使用时,可以注释掉 //e.printStackTrace(); } } list.add(obj); } model.setList(list); return model; } //main测试 public static void main(String[] args) throws Exception { FenYeModel model= getRecordsByPage(Emp.class,"emp","*",3,5,"",""); for (Object e : model.getList()) { System.out.println((Emp)e); } } }
希望可以帮助到大家!有不足还望大神指出...
最后附上源码链接:https://pan.baidu.com/s/1OBTpEXC2gHAxhYLzYDTOSg
以上是关于Oracle 分页存储过程的主要内容,如果未能解决你的问题,请参考以下文章