首先:还是先把存储过程写好!(关于对一张表的分页查询)
--因为现在好多Web App,在JS端口都有封装好的grid控件,所以这里,只传开始记录数,和结束记录就可以了。简单的练习而已
CREATE OR REPLACE PROCEDURE PROC_PAGINATION(
START_NUM IN INT --输入参数:分页的开始记录数
,END_NUM IN INT --输入参数:分页的结束记录数
,TOTAL_COUNT OUT INT --输出参数:总记录数
,PAGE_RESULT_SET OUT SYS_REFCURSOR --Oracle的游标查询结果集
) AS
COUNT_SQL VARCHAR2(200); --定义变量:查询总记录数的SQL
V_SQL VARCHAR2(400); --定义变量:分页查询结果集的SQL
BEGIN
COUNT_SQL := 'SELECT COUNT(*) FROM MYMIS.TB_MYMIS_RESOURCES_MENU';
EXECUTE IMMEDIATE COUNT_SQL INTO TOTAL_COUNT; --把查询的记录数结果,给输出参数
--V_SQL := 'SELECT * FROM (SELECT TEMP.*,ROWNUM AS RN FROM (SELECT * FROM MYMIS.TB_MYMIS_RESOURCES_MENU ORDER BY RESOURCE_ID ASC) TEMP WHERE ROWNUM <= ' || END_NUM || ') WHERE RN > ' || START_NUM;
V_SQL := 'SELECT * FROM (SELECT ROWNUM AS RN,A.* FROM MYMIS.TB_MYMIS_RESOURCES_MENU A WHERE ROWNUM <= ' || END_NUM || ' ORDER BY A.RESOURCE_ID ASC) WHERE RN > ' || START_NUM;
OPEN PAGE_RESULT_SET FOR V_SQL; --把游标查询的结果集给输出参数END PROC_PAGINATION;
END PROC_PAGINATION;
存储过程写好了,下面是普通JDBC类的调用:(这里就写了一个main方法,做测试用)
public static void main(String[] args) {
// Connection con = ConnectionFactory.getConnection();
// if (con != null) {
// System.out.println("连接正常...");
// } else {
// System.out.println("连接出错...");
// }
Connection conn = ConnectionFactory.getConnection(); //获取数据库连接
CallableStatement cs; //定义JDBC调用存储过程的类
try {
cs = conn.prepareCall("call MYMIS.PROC_PAGINATION(?,?,?,?)"); //调用存储过程
cs.setInt(1, 4); //匹配输入,输出参数
cs.setInt(2, 8);
cs.registerOutParameter(3, Types.INTEGER);
cs.registerOutParameter(4, oracle.jdbc.OracleTypes.CURSOR);
cs.execute(); //执行存储过程
int totalPage = cs.getInt(3); //将输出参数给一个变量
System.out.println("共有" + totalPage + "页");
ResultSet rs = (ResultSet) cs.getObject(4); //将输出结果集,给一个ResultSet
while (rs.next()) {
System.out.println(rs.getString("RESOURCE_ID")+","+rs.getString("RESOURCE_NAME") +"," + rs.getString("RESOURCE_TYPE"));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
下面做了一个JdbcTemplate的调用,个人觉得数据库持久层,spring的JdbcTemplate是个好东西,查询效率也蛮快的,而且查询方法也很多。同样写在main方法里
public static void main(String[] args) {
ClassPathXmlApplicationContext appctx = new ClassPathXmlApplicationContext("applicationContext.xml"); //读取spring的全局配置文件
JdbcTemplate jdbcTemplate = (JdbcTemplate) appctx.getBean("jdbcTemplate"); //通过BeanId,从Bean工厂里获取到定义的jdbcTemplate对象类,如果不这样new 出来JdbcTemplate为null
// Object[] params = new Object[] { "111", "test", "99", "测试地市", "888",
// "测试部门", "888888", "2" };
jdbcTemplate.execute("call MYMIS.PROC_PAGINATION(?,?,?,?)");
//jdbcTemplate.execute这样去调用存储过程,jdbcTemplate.execute(CallableStatementCreator arg0, CallableStatementCallback arg1) 两个参数,一个是创建调用存储过程对象,另一个是返回参数
List resultList = (List)jdbcTemplate.execute(
new CallableStatementCreator(){
public CallableStatement createCallableStatement(
Connection con) throws SQLException {
String storedProc = "{call MYMIS.PROC_PAGINATION(?,?,?,?)}";//调用存储过程
CallableStatement cs = con.prepareCall(storedProc);
cs.setInt(1, 4); //匹配输入输出参数
cs.setInt(2, 8);
cs.registerOutParameter(3, Types.INTEGER);
cs.registerOutParameter(4, oracle.jdbc.OracleTypes.CURSOR);
return cs; //返回execute()方法的第一个参数,创建CallableStatement的对象
}
},new CallableStatementCallback() {
public Object doInCallableStatement(CallableStatement cs)
throws SQLException, DataAccessException {
List resultsMap = new ArrayList();
cs.execute();
int count = cs.getInt(3); //输出参数1
System.out.println(count);
ResultSet rs = (ResultSet) cs.getObject(4); //输入出结果集
while (rs.next()) {// 转换每行的返回值到Map中
Map rowMap = new HashMap();
//rowMap.put("total", count);
rowMap.put("rs", rs);
System.out.println(rs.getString("RESOURCE_NAME"));
resultsMap.add(rowMap);//返回execute()方法的第二个参数,CallableStatementCallback的对象
}
rs.close();
return resultsMap; //将整个调用存储过程得到的参数返回。
}
}
);
}
大致就是这样的,代码都经过本机测试过的!!感觉很多数据库的存储过程写法有些差异,不过都大同小异。