`

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

    博客分类:
  • 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
通过名称去操作可能会比通过下标去操作的可读性强一些

相关推荐

    pb调用存储过程

    4. **DataWindow对象**:如果你想要在DataWindow中使用存储过程,可以设置DataWindow的SQL源为存储过程,然后在适当的方法(如RowChange, Fetch等)中调用执行。 其次,关于**存储过程的创建**,在提供的描述中,...

    java 调用存储过程

    在这个例子中,我们创建了一个`CallableStatement`实例,设置参数值,然后执行存储过程。执行后,我们从结果集中获取并处理数据。 值得注意的是,上述代码中的文件名列表(如Project1.cfg、Unit1.dcu等)与Java调用...

    Informatica调用存储过程图文流程

    1. 新建一个 Mapping:在 Informatica 中,创建一个新的 Mapping,用于调用存储过程。Mapping 是 Informatica 中的一种数据集成单元,用于将数据从源系统移到目标系统。 2. 右键目标表-》Edit:在 Mapping 中,右键...

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

    6. **执行存储过程**:调用`CallableStatement`的`execute()`方法执行存储过程。 7. **获取OUT参数**:执行后,使用`getXXX()`方法(与之前设置`OUT`参数时的`setXXX()`对应)获取返回值。例如,如果`OUT`参数是...

    JDBC 调用存储过程方法

    5. **执行存储过程**:使用`CallableStatement`的`execute()`方法执行存储过程。 ```java cs.execute(); ``` 6. **获取结果**:如果存储过程有输出参数或返回结果集,可以使用`getXXX()`方法获取。例如,获取...

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

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

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

    执行存储过程很简单,只需要调用命令对象的`Execute`方法即可。示例代码如下: ```vb Dim ADORs As ADODB.Recordset Set ADORs = ADOCmd.Execute ``` 在这个例子中,`Execute`方法将返回一个记录集对象,我们可以...

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

    ### C#调用Oracle方法(包括调用存储过程) 在.NET框架中,使用C#语言进行数据库操作是一项常见的任务。本文将详细介绍如何使用C#语言连接Oracle数据库,并演示如何调用Oracle存储过程,特别是带有输出参数的情况。...

    NHibernate调用存储过程全集,值.

    除了映射文件,还可以在运行时动态创建SQLQuery对象来执行存储过程,这适用于那些不需要持久化到实体类的结果。例如: ```csharp string sql = "EXEC usp_CustomProcedure :param1"; SQLQuery query = session....

    hibernate调用存储过程的方法调用

    - **执行存储过程**:调用`executeUpdate`或`list`方法执行存储过程。对于无返回值的存储过程,通常使用`executeUpdate`;如果有结果集,可以使用`list`获取并处理结果。 - **处理结果**:如果存储过程返回结果,...

    在VB6.0中调用SQL Server的存储过程.pdf

    然后,需要创建一个Command对象,用于执行存储过程。最后,需要将存储过程作为一个参数传递给Command对象,然后执行该存储过程。 在VB6.0中调用SQL Server的存储过程需要了解存储过程的优点和使用方法,并遵守一定...

    ibatIS调用存储过程

    2. **创建Mapper接口**:在Java代码中,创建一个Mapper接口,这个接口的方法名应该与存储过程的逻辑相匹配,返回值类型根据存储过程的输出参数确定。如果存储过程有输出参数,那么需要在接口方法中定义这些参数,并...

    启动SQL Server时自动执行存储过程

    启动 SQL Server 时自动执行存储过程是 SQL Server 中的一项功能,它允许在 SQL Server 启动时自动执行一个或多个存储过程。这些存储过程必须由系统管理员创建,并在 sysadmin 固定服务器角色下作为后台过程执行。 ...

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

    `prepareCall`方法用于创建一个`CallableStatement`对象,该对象用于执行存储过程或函数调用。其中`"{call proc_select(?,?)}"`是一个调用存储过程的SQL语句,`?`代表参数占位符。 4. **设置输入参数**: ```java...

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

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

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

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

    hibernate调用存储过程

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

    sqlhelper调用存储过程.rar

    2. 使用ExecuteNonQuery、ExecuteReader或ExecuteScalar方法:SqlHelper提供了这三种方法来执行存储过程。 - ExecuteNonQuery:用于执行不返回结果集的存储过程,如INSERT、UPDATE、DELETE等操作。 - ...

Global site tag (gtag.js) - Google Analytics