文档章节

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

zchuanzhao
 zchuanzhao
发布于 2015/09/30 15:42
字数 2154
阅读 149
收藏 3

这几天在做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;
	}

}

© 著作权归作者所有

zchuanzhao

zchuanzhao

粉丝 51
博文 244
码字总数 145913
作品 1
福州
程序员
私信 提问
spring中的JdbcTemplate简单记录

JdbcTemplate主要提供以下五类方法: execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句; update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate...

刘谱_smile
2015/07/15
146
0
Spring JdbcTemplate方法详解

JdbcTemplate主要提供以下五类方法: execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句; update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate...

zqcju
2014/06/13
66.8K
6
JDBC Statement PreparedStatement CallableStatement

在 JDBC 应用程序中,JDBC 语句对象用于将 SQL 语句发送到数据库服务器。一个语句对象与一个连接相关联,应用程序与数据库服务器之间的通信由语句对象来处理。 JDBC 中有三种类型的语句对象:...

learn_more
2014/12/13
197
0
对JDBC的支持 之 7.2 JDBC模板类

JDBC模板类 概述 Spring JDBC抽象框架core包提供了JDBC模板类,其中JdbcTemplate是core包的核心类,所以其他模板类都是基于它封装完成的,JDBC模板类是第一种工作模式。 JdbcTemplate类通过模...

heroShane
2014/02/27
431
0
Spring 对JDBC操作的支持

在用JDBC进行数据库的操作的时候会在每个DAO中写有很多重复和类似的代码(建立连接,关闭连接等等),Spring的JDBC框架对这些重复的操作做了提取,形成了模板,使用Spring的JDBC框架的开发者通过提...

晨曦之光
2012/04/25
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

mysql-connector-java升级到8.0后保存时间到数据库出现了时差

在一个新项目中用到了新版的mysql jdbc 驱动 <dependency>     <groupId>mysql</groupId>     <artifactId>mysql-connector-java</artifactId>     <version>8.0.18</version> ......

ValSong
今天
5
0
Spring Boot 如何部署到 Linux 中的服务

打包完成后的 Spring Boot 程序如何部署到 Linux 上的服务? 你可以参考官方的有关部署 Spring Boot 为 Linux 服务的文档。 文档链接如下: https://docs.ossez.com/spring-boot-docs/docs/r...

honeymoose
今天
6
0
Spring Boot 2 实战:使用 Spring Boot Admin 监控你的应用

1. 前言 生产上对 Web 应用 的监控是十分必要的。我们可以近乎实时来对应用的健康、性能等其他指标进行监控来及时应对一些突发情况。避免一些故障的发生。对于 Spring Boot 应用来说我们可以...

码农小胖哥
今天
9
0
ZetCode 教程翻译计划正式启动 | ApacheCN

原文:ZetCode 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远。 ApacheCN 学习资源 贡献指南 本项目需要校对,欢迎大家提交 Pull Request。 ...

ApacheCN_飞龙
今天
5
0
CSS定位

CSS定位 relative相对定位 absolute绝对定位 fixed和sticky及zIndex relative相对定位 position特性:css position属性用于指定一个元素在文档中的定位方式。top、right、bottom、left属性则...

studywin
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部