JAVA执行存储过程,存储过程既有更新操作,又有返回结果集的处理方法总结

本文介绍了一种在Java中处理复杂存储过程返回结果的方法,包括单个和多个结果集的处理,尤其适用于包含更新操作及多结果集的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这几天在做JAVA执行存储过程获取返回集的功能,因为之前都没做过存储过程的,所以一开始就去搜索,因为用到的存储过程返回结果各种各样,有只返回一个结果集的,有返回多结果集的,有的是先做更新、建虚拟表做插入操作再返回多个结果集,可惜网络上讲的返回多结果集都是确定只返回结果集,存储过程不做更新等操作,所以用网络上讲的方法不能用。研究了很久,至于找到了一个方法,现在做下代码总结。

以下的封装好的类,有各种情况,可以参考下,因为是跟我现在做的项目业务结合起来,可能有些看的不太懂,大家只要看核心的代码就可以了。

package com.evideostb.billsystem.common.dao.impl;

import java.lang.reflect.InvocationTargetException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;
import org.apache.commons.lang.StringUtils;

import com.evideostb.billsystem.common.dao.IBaseDAO;
import com.evideostb.billsystem.module.model.ResponseProtocolListMap;
import com.evideostb.billsystem.module.model.ResponseProtocolMap;
import com.evideostb.billsystem.utils.ConnectionPool;


/**
 * 数据操作基类
 * @author zhangchuanzhao
 * 2015-9-14 上午9:26:21
 */
public class BaseDAOImpl implements IBaseDAO {
	
	/**
	 * 从多结果集返回一个结果集列表的存储过程
	 * 该方法中,最后3个参数是返回参数:@ErrorCode,@ErrorMessage,@ExceptMessage
	 * 如果存储过程没有这3个返回参数,不要调用此方法
	 * 该方法包括查询前面有执行更新、增加、删除操作,最后返回一个结果集的情况
	 * @param howMany 希望得到的第几个返回集,必须大于0
	 * @param call 存储过程,如:dbo.BL_HV_QueryCheckOutInfo(?,?,?,?,?,?,?,?)
	 * @param objs 参数集,如:"2015-09-01","2015-10-01","",0,0,0,"",""
	 * @return 结果集
	 */
	@SuppressWarnings("resource")
	@Override
	public ResponseProtocolListMap spMoreResultSetList(int howMany, String call, Object...objs){
		ResponseProtocolListMap responseProtocolListMap = new ResponseProtocolListMap();
		List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
		Connection conn = ConnectionPool.getConnection();
		CallableStatement cst = null;
		ResultSet rs = null;
		try {
			cst = conn.prepareCall("{call "+call+"}");
			if(objs != null){
				for (int i = 0; i < objs.length; i++) {
					cst.setObject(i+1, objs[i]);
				}
			}
			cst.registerOutParameter(objs.length-2, Types.INTEGER);
			cst.registerOutParameter(objs.length-1, Types.VARCHAR);
			cst.registerOutParameter(objs.length, Types.VARCHAR);
			
			cst.execute();
			rs = cst.getResultSet();
			//更新的数据条数,更新操作的时候,该值大于等于0,有结果集或者没有更新并且没有结果集的时候,该值为-1,
			int updateCount = cst.getUpdateCount();
			//计算遍历过有返回集的个数
			int hasResultSetNum = 0;
			//只有当有更新操作或者有返回结果集的时候,才循环
			while((updateCount != -1) || (updateCount == -1 && rs != null)){
	            if(rs != null){
	            	hasResultSetNum ++;
	            	if(hasResultSetNum == howMany){
	            		ResultSetMetaData rsmd = rs.getMetaData();
		    			int colcount = rsmd.getColumnCount();
		    			while (rs.next()) {
		    				Map<String, Object> map = new HashMap<String, Object>();
		    				// rs-->map
		    				for (int i = 1; i <= colcount; i++) {
		    					String colname = rsmd.getColumnName(i);
		    					String value = rs.getString(i);
		    					//值为null的不返回
		    					if(!StringUtils.equals(value, null)){
		    						map.put(colname, value);
		    					}
		    				}
		    				resultList.add(map);
		    			}
		    			break;
	            	}
	            }
	            cst.getMoreResults();
            	updateCount = cst.getUpdateCount();
            	rs = cst.getResultSet();
			}
            //设置返回结果代码
			responseProtocolListMap.setErrorCode(cst.getInt(objs.length-2)+"");
			responseProtocolListMap.setErrorMessage(cst.getString(objs.length-1));
			responseProtocolListMap.setExceptMessage(cst.getString(objs.length));
			responseProtocolListMap.setResponseInfo(resultList);
		}catch (Exception e) {
			e.printStackTrace();
		} finally {
			ConnectionPool.release(conn, cst, rs);
		}
		return responseProtocolListMap;
	}
	
	/**
	 * 返回列表的单结果集的存储过程
	 * 该方法不支持查询前面有执行更新、增加、删除操作,最后返回一个结果集的情况
	 * 该方法中,最后3个参数是返回参数:@ErrorCode,@ErrorMessage,@ExceptMessage
	 * 如果存储过程没有这3个返回参数,不要调用此方法
	 * @param call 存储过程,如:dbo.BL_HV_QueryCheckOutInfo(?,?,?,?,?,?,?,?)
	 * @param objs 参数集,如:"2015-09-01","2015-10-01","",0,0,0,"",""
	 * @return 结果集
	 */
	@Override
	public ResponseProtocolListMap spOneResultSetList(String call, Object...objs){
		ResponseProtocolListMap responseProtocolListMap = new ResponseProtocolListMap();
		List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
		Connection conn = ConnectionPool.getConnection();
		CallableStatement cst = null;
		ResultSet rs = null;
		try {
			cst = conn.prepareCall("{call "+call+"}");
			if(objs != null){
				for (int i = 0; i < objs.length; i++) {
					cst.setObject(i+1, objs[i]);
				}
			}
			//注册返回参数
			cst.registerOutParameter(objs.length-2, Types.INTEGER);
			cst.registerOutParameter(objs.length-1, Types.VARCHAR);
			cst.registerOutParameter(objs.length, Types.VARCHAR);
			rs = cst.executeQuery();
			
            if(rs != null){
            	ResultSetMetaData rsmd = rs.getMetaData();
    			int colcount = rsmd.getColumnCount();
    			while (rs.next()) {
    				Map<String, Object> map = new HashMap<String, Object>();
    				// rs-->map
    				for (int i = 1; i <= colcount; i++) {
    					String colname = rsmd.getColumnName(i);
    					String value = rs.getString(i);
    					//值为null的不返回
    					if(!StringUtils.equals(value, null)){
    						map.put(colname, value);
    					}
    				}
    				resultList.add(map);
    			}
            }
	        //设置返回结果代码
			responseProtocolListMap.setErrorCode(cst.getInt(objs.length-2)+"");
			responseProtocolListMap.setErrorMessage(cst.getString(objs.length-1));
			responseProtocolListMap.setExceptMessage(cst.getString(objs.length));
		}catch (Exception e) {
			e.printStackTrace();
		} finally {
			ConnectionPool.release(conn, cst, rs);
		}
		responseProtocolListMap.setResponseInfo(resultList);
		System.out.println("size:"+resultList.size());
		return responseProtocolListMap;
	}
	
	/**
	 * 返回多结果集中的一个结果集单条记录的存储过程
	 * 该方法中,最后3个参数是返回参数:@ErrorCode,@ErrorMessage,@ExceptMessage
	 * 如果存储过程没有这3个返回参数,不要调用此方法
	 * 该方法包括查询前面有执行更新、增加、删除操作,最后返回一条记录一个结果集的情况
	 * @param howMany 希望得到的第几个返回集,必须大于0
	 * @param call 存储过程,如:dbo.BL_HV_QueryCheckOutInfo(?,?,?,?,?,?,?,?)
	 * @param objs 参数集,如:"2015-09-01","2015-10-01","",0,0,0,"",""
	 * @return 结果集
	 */
	@SuppressWarnings("resource")
	@Override
	public ResponseProtocolMap spMoreResultSetMap(int howMany, String call, Object...objs){
		ResponseProtocolMap responseProtocolMap = new ResponseProtocolMap();
		Connection conn = ConnectionPool.getConnection();
		CallableStatement cst = null;
		ResultSet rs = null;
		try {
			cst = conn.prepareCall("{call "+call+"}");
			if(objs != null){
				for (int i = 0; i < objs.length; i++) {
					cst.setObject(i+1, objs[i]);
				}
			}
			cst.registerOutParameter(objs.length-2, Types.INTEGER);
			cst.registerOutParameter(objs.length-1, Types.VARCHAR);
			cst.registerOutParameter(objs.length, Types.VARCHAR);
			
			cst.execute();
			rs = cst.getResultSet();
			//更新的数据条数,更新操作的时候,该值大于等于0,有结果集或者没有更新并且没有结果集的时候,该值为-1,
			int updateCount = cst.getUpdateCount();
			//计算遍历过有返回集的个数
			int hasResultSetNum = 0;
			//只有当有更新操作或者有返回结果集的时候,才循环
			while((updateCount != -1) || (updateCount == -1 && rs != null)){
	            if(rs != null){
	            	hasResultSetNum ++;
	            	if(hasResultSetNum == howMany){
	            		ResultSetMetaData rsmd = rs.getMetaData();
		    			int colcount = rsmd.getColumnCount();
		    			if(rs.next()){
		    				Map<String, Object> map = new HashMap<String, Object>();
		    				// rs-->map
		    				for (int i = 1; i <= colcount; i++) {
		    					String colname = rsmd.getColumnName(i);
		    					String value = rs.getString(i);
		    					//值为null的不返回
		    					if(!StringUtils.equals(value, null)){
		    						map.put(colname, value);
		    					}
		    				}
		    				responseProtocolMap.setResponseInfo(map);
		    			}
	            	}
	            }
	            cst.getMoreResults();
            	updateCount = cst.getUpdateCount();
            	rs = cst.getResultSet();
			}
            //设置返回结果代码
            responseProtocolMap.setErrorCode(cst.getInt(objs.length-2)+"");
            responseProtocolMap.setErrorMessage(cst.getString(objs.length-1));
            responseProtocolMap.setExceptMessage(cst.getString(objs.length));
		}catch (Exception e) {
			e.printStackTrace();
		} finally {
			ConnectionPool.release(conn, cst, rs);
		}
		return responseProtocolMap;
	}
	
	/**
	 * 返回单条记录的单结果集
	 * 该方法不支持查询前面有执行更新、增加、删除操作,最后返回一个结果集的情况
	 * 该方法中,最后3个参数是返回参数:@ErrorCode,@ErrorMessage,@ExceptMessage
	 * 如果存储过程没有这3个返回参数,不要调用此方法
	 * @param call 存储过程,如:dbo.BL_HV_QueryCheckOutInfo(?,?,?,?,?,?,?,?)
	 * @param objs 参数集,如:"2015-09-01","2015-10-01","",0,0,0,"",""
	 * @return 结果集
	 */
	@Override
	public ResponseProtocolMap spOneResultSetMap(String call, Object...objs){
		ResponseProtocolMap responseProtocolMap = new ResponseProtocolMap();
		Connection conn = ConnectionPool.getConnection();
		CallableStatement cst = null;
		ResultSet rs = null;
		try {
			cst = conn.prepareCall("{call "+call+"}");
			if(objs != null){
				for (int i = 0; i < objs.length; i++) {
					cst.setObject(i+1, objs[i]);
				}
			}
			//注册返回参数
			cst.registerOutParameter(objs.length-2, Types.INTEGER);
			cst.registerOutParameter(objs.length-1, Types.VARCHAR);
			cst.registerOutParameter(objs.length, Types.VARCHAR);
			rs = cst.executeQuery();
			
            if(rs != null){
            	ResultSetMetaData rsmd = rs.getMetaData();
    			int colcount = rsmd.getColumnCount();
    			if(rs.next()){
    				Map<String, Object> map = new HashMap<String, Object>();
    				// rs-->map
    				for (int i = 1; i <= colcount; i++) {
    					String colname = rsmd.getColumnName(i);
    					String value = rs.getString(i);
    					//值为null的不返回
    					if(!StringUtils.equals(value, null)){
    						map.put(colname, value);
    					}
    				}
    				responseProtocolMap.setResponseInfo(map);
    			}
            }
	        //设置返回结果代码
            responseProtocolMap.setErrorCode(cst.getInt(objs.length-2)+"");
            responseProtocolMap.setErrorMessage(cst.getString(objs.length-1));
            responseProtocolMap.setExceptMessage(cst.getString(objs.length));
		}catch (Exception e) {
			e.printStackTrace();
		} finally {
			ConnectionPool.release(conn, cst, rs);
		}
		return responseProtocolMap;
	}


	/**
	 * 返回所有的多结果集中记录的存储过程
	 * 该方法中,最后3个参数是返回参数:@ErrorCode,@ErrorMessage,@ExceptMessage
	 * 如果存储过程没有这3个返回参数,不要调用此方法
	 * 该方法包括查询前面有执行更新、增加、删除操作,最后返回所有的结果集的情况
	 * @param call 存储过程,如:dbo.BL_HV_QueryCheckOutInfo(?,?,?,?,?,?,?,?)
	 * @param objs 参数集,如:"2015-09-01","2015-10-01","",0,0,0,"",""
	 * @return 结果集
	 */
	@SuppressWarnings("resource")
	@Override
	public ResponseProtocolMap spGetAllMoreResultSetMap(String call,
			Object... objs) {
		ResponseProtocolMap responseProtocolMap = new ResponseProtocolMap();
		Map<String, Object> responseInfo = new HashMap<String, Object>();
		Connection conn = ConnectionPool.getConnection();
		CallableStatement cst = null;
		ResultSet rs = null;
		try {
			cst = conn.prepareCall("{call "+call+"}");
			if(objs != null){
				for (int i = 0; i < objs.length; i++) {
					cst.setObject(i+1, objs[i]);
				}
			}
			//注册返回参数
			cst.registerOutParameter(objs.length-2, Types.INTEGER);
			cst.registerOutParameter(objs.length-1, Types.VARCHAR);
			cst.registerOutParameter(objs.length, Types.VARCHAR);
			
			cst.execute();
			rs = cst.getResultSet();
			//更新的数据条数,更新操作的时候,该值大于等于0,有结果集或者没有更新并且没有结果集的时候,该值为-1,
			int updateCount = cst.getUpdateCount();
            int j = 0;
			//只有当有更新操作或者有返回结果集的时候,才循环
			while((updateCount != -1) || (updateCount == -1 && rs != null)){
            	j ++;
            	if(rs != null){
                	List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
                	ResultSetMetaData rsmd = rs.getMetaData();
        			int colcount = rsmd.getColumnCount();
        			while(rs.next()){
        				Map<String, Object> map = new HashMap<String, Object>();
        				// rs-->map
        				for (int i = 1; i <= colcount; i++) {
        					String colname = rsmd.getColumnName(i);
        					String value = rs.getString(i);
        					//值为null的不返回
        					if(!StringUtils.equals(value, null)){
        						map.put(colname, value);
        					}
        				}
        				list.add(map);
        			}
        			responseInfo.put("Level_"+j, list);
            	}
            	
            	cst.getMoreResults();
            	updateCount = cst.getUpdateCount();
            	rs = cst.getResultSet();
            }
            responseProtocolMap.setResponseInfo(responseInfo);
	        //设置返回结果代码
            responseProtocolMap.setErrorCode(cst.getInt(objs.length-2)+"");
            responseProtocolMap.setErrorMessage(cst.getString(objs.length-1));
            responseProtocolMap.setExceptMessage(cst.getString(objs.length));
		}catch (Exception e) {
			e.printStackTrace();
		} finally {
			ConnectionPool.release(conn, cst, rs);
		}
		return responseProtocolMap;
	}

}

转载于:https://my.oschina.net/zchuanzhao/blog/512872

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值