1. 程式人生 > >Oracle 分頁存儲過程

Oracle 分頁存儲過程

tps 測試 code iat ini arr cat tcl 保存

--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)+"\t");
            System.out.print(rs.getObject(2)+"\t");
            System.out.print(rs.getObject(3)+"\t");
            System.out.print(rs.getObject(4)+"\t");
            System.out.print(rs.getObject(5)+"\t");
            System.out.print(rs.getObject(6)+"\t");
            System.out.println(rs.getObject(7)+"\t");
        }
        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 分頁存儲過程