`

今天写了一个调用存储过程的方法

    博客分类:
  • SSH
SQL 
阅读更多

1、接口

    /**
	 * 调用存储过程
	 * 
	 * @param procName 存储过程名. 如:testProcParam、mypack.testProcParam
	 * @param inParams 输入参数映射对象. 格式为:索引号->值
	 * @param outTypes 输出参数类型映射对象. 格式为:索引号->类型
	 * @return Map<Integer, Object> 输出结果映射对象. 格式为:索引号->值
	 */
	public Map<Integer, Object> callProcedure(String procName, 
			Map<Integer, Object> inParams, Map<Integer, Integer> outTypes);
 

 

2、实现方法

	public Map<Integer, Object> callProcedure(final String procName,
			final Map<Integer, Object> inParams, final Map<Integer, Integer> outTypes) {
		return (Map<Integer, Object>) getHibernateTemplate().executeWithNativeSession(new HibernateCallback(){
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				// 输出参数结果
				Map<Integer, Object> resultMap = new HashMap<Integer, Object>();
				
				// 参数个数
				int paramCount = 0;
				
				// 存放问号的字符串. 如?或?,?...
				String questionMark = "";
				
				// 计算问号个数
				if (MapUtils.isNotEmpty(inParams)) {
					paramCount += inParams.size();
				}
				if (MapUtils.isNotEmpty(outTypes)) {
					paramCount += outTypes.size();
				}
				
				// 设置问号字符串, 以逗号隔开
				for (int i = 0; i < paramCount; i++) {
					questionMark += "?,";
				}
				if (!"".equals(questionMark)) questionMark = questionMark.substring(0, questionMark.length() - 1);

				// 获取数据库连接
				Connection con = session.connection();
				
				// 创建调用存储过程的CallableStatement对象
				String sql = "{call " + procName + "(" + questionMark + ")}";
				CallableStatement cstmt = con.prepareCall(sql);
				
				// 设置输入参数
				if (MapUtils.isNotEmpty(inParams))
					for (Map.Entry<Integer, Object> entry : inParams.entrySet()) {
						cstmt.setObject(entry.getKey(), entry.getValue());
					}

				// 注册输出参数
				if (MapUtils.isNotEmpty(outTypes))
					for (Map.Entry<Integer, Integer> entry : outTypes.entrySet()) {
						cstmt.registerOutParameter(entry.getKey(), entry.getValue());
					}
				
				// 执行存储过程
				cstmt.execute();

				// 获取输出参数结果
				if (MapUtils.isNotEmpty(outTypes))
					for (Map.Entry<Integer, Integer> entry : outTypes.entrySet()) {
						resultMap.put(entry.getKey(), cstmt.getObject(entry.getKey()));
					}
				
				return resultMap;
			}
		});
	}
 

 

3、使用

		String procName = "PACK_TASK.PROC_SOFTWORE_UPDATE_ANALYZE"; // 存储过程名
		Map<Integer, Object> inParams = new HashMap<Integer, Object>(); // 输入参数. 格式为:索引号->值
		Map<Integer, Integer> outTypes = new HashMap<Integer, Integer>(); // 输出参数类型. 格式为:索引号->类型
		
		// 设置输入参数
		inParams.put(1, taskId);
		
		// 设置输出类型
		outTypes.put(2, Types.INTEGER);
		outTypes.put(3, Types.VARCHAR);
		
		// 调用存储过程
		Map<Integer, Object> resultMap = softwareResultRepository.callProcedure(procName, inParams, outTypes);
		
		// 获取输出参数值
		resultMap.get(2);
		resultMap.get(3);
 

 

 

4
1
分享到:
评论
2 楼 zhanjia 2011-08-12  
huang_yong 写道
封装得不错!

问题一:
if (questionMark != "") questionMark = questionMark.substring(0, questionMark.length() - 1);
以上代码 questionMark != "" 貌似应该写成 !questionMark.equals("");

问题二:
获取 Connection 目前部推荐使用:
session.connection()
可考虑使用:
SessionFactoryUtils.getDataSource(hibernateTemplate.getSessionFactory()).getConnection()

建议:
将 inParams 与 outTypes 这两个 Map 的 key 类型定义为 String类型
Map<String, Object> inParams
Map<String, Integer> outTypes
通过名称去操作可能会比通过下标去操作的可读性强一些


谢谢您的指正与建议!
问题一已更正
问题二可以根据实际情况适当优化
1 楼 huang_yong 2011-08-07  
封装得不错!

问题一:
if (questionMark != "") questionMark = questionMark.substring(0, questionMark.length() - 1);
以上代码 questionMark != "" 貌似应该写成 !questionMark.equals("");

问题二:
获取 Connection 目前部推荐使用:
session.connection()
可考虑使用:
SessionFactoryUtils.getDataSource(hibernateTemplate.getSessionFactory()).getConnection()

建议:
将 inParams 与 outTypes 这两个 Map 的 key 类型定义为 String类型
Map<String, Object> inParams
Map<String, Integer> outTypes
通过名称去操作可能会比通过下标去操作的可读性强一些

相关推荐

    springboot mybatis 动态调用oracle存储过程,通过存储过程名称,就能动态调用存储过程、java动态调用or

    能不能写个动态的业务,只输入存储过程名称,自动...只写一个通用方法,就可以调用所有的存储过程。只根据输入不同的存储过程名称、参数内容,自动调用不同的存储过程。 已经使用在多个项目中 全开源项目 请放心下载

    java 调用存储过程

    java 调用存储过程java 调用存储过程java 调用存储过程java 调用存储过程java 调用存储过程java 调用存储过程java 调用存储过程

    birt调用存储过程

    birt报表中调用存储过程的方法. ... 调用一个含有参数的存储过程,并且有输出参数。 6 调用含有RETURN参数的存储过程 7 调用返回游标的存储过程 7 调用返回多个结果集的存储过程 8 6. 参考文档和资源 11

    C# winform调用SQL存储过程-菜鸟入门 详细注释

    内容概要:简单的C# winform调用存储过程实例,创建存储过程入参,通过SqlConnection对象和SqlCommand对象调用存储过程,获取存储过程的出参并显示出来,详细代码注释,希望对用到C#调用存储过程的小伙伴有帮助 ...

    JDBC 调用存储过程方法

    jdbc 存储过程 java 程序 JDBC 调用存储过程方法

    Python使用cx_Oracle调用Oracle存储过程的方法示例

    本文实例讲述了Python使用cx_Oracle调用Oracle存储过程的方法。分享给大家供大家参考,具体如下: 这里主要测试在Python中通过cx_Oracle调用PL/SQL。 首先,在数据库端创建简单的存储过程。 create or replace ...

    hibernate调用存储过程

    hibernate调用存储过程 hibernate调用存储过程 hibernate调用存储过程 hibernate调用存储过程 hibernate调用存储过程 hibernate调用存储过程 hibernate调用存储过程

    调用oracle存储过程的公用方法

    C#调用oracle存储过程的通用方法 C#调用oracle存储过程的通用方法

    Java调用存储过程的2种方法

    Java调用存储过程的2种方法 Java调用存储过程的2种方法 Java调用存储过程的2种方法

    pb调用存储过程

    Pb 调用 DECLARE lpro_test PROCEDURE FOR proc_pslx; EXECUTE lpro_test ; 存储过程 CREATE PROCEDURE proc_pslx AS insert into demo(name) values('55566') GO

    C#调用oracle方法(包括调用存储过程)

    详细的记录了C#如何调用oracle以及带有存储过程输出变量的方法,适合初学者。

    VC ADO调用存储过程

    关于ADO调用存储过程的标准的做法:按照以下步骤进行:  1、生成并初始化一个_CommandPtr对象;... 5、使用_CommandPtr的Execute方法调用存储过程;  6、从结果中获取返回参数的值(如果有的话)。

    java调用存储过程

    java,调用存储过程java,调用存储过程java,调用存储过程java,调用存储过程java,调用存储过程java,调用存储过程java,调用存储过程java,调用存储过程java,调用存储过程java,调用存储过程java,调用存储过程

    VB6.0 调用存储过程的例子(方法一)

    VB6.0 调用存储过程的例子(方法一) rm1窗体,Copy以下的代码到窗体中,该段代码将测试存储过程ADOTestRPE的返回值、输入参数及输出参数,测试的过程中,可能需要修改链接字符串。

    金蝶K3插件开发调用存储过程

    金蝶K3插件开发调用存储过程

    dapper的调用各种存储过程的方法

    dapper的调用各种存储过程的方法的帮助类文档,可通过该文档了解并学会使用Dapper,并且调用Dapper

    c#调用存储过程两种方法 - - c# sql .net asp.net

    c#调用存储过程两种方法 - - c# sql .net asp.net

    sqlhelper调用存储过程.rar

    sqlhelper调用存储过程,sqlhelper调用存储过程方法,sqlhelper怎样调用存储过程

    java调用存储过程(含out参数)

    java调用存储过程的方法,含还有out参数的存储过程,解决方案,在网上找了n久发现这样的资源太少,现在总结一下我的解决方案供大家分享,希望对大家有用

    c#调用存储过程例子

    c#调用存储过程例子c#调用存储过程例子c#调用存储过程例子c#调用存储过程例子c#调用存储过程例子c#调用存储过程例子c#调用存储过程例子c#调用存储过程例子c#调用存储过程例子c#调用存储过程例子

Global site tag (gtag.js) - Google Analytics