好久没有写博客了,今天又来写一篇,工作都好久没有用到Oracle数据库了,昨天做了一个Oracle数据库存储过程的例子,用JAVA APP去调用,现在把代码传上来:
首先:还是先把存储过程写好!(关于对一张表的分页查询)
--因为现在好多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; //将整个调用存储过程得到的参数返回。 } } ); }大致就是这样的,代码都经过本机测试过的!!感觉很多数据库的存储过程写法有些差异,不过都大同小异。