博客统计信息

用户名:lee_json
文章数:36
评论数:8
访问量:16850
无忧币:142
博客积分:230
博客等级:2
注册日期:2010-04-14

Ibatis调用Oracle存储过程,以及返回Cursor结果集的问题
2010-12-10 08:48:25
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://keyvalue.blog.51cto.com/1475446/450113

     最近开始接触Oracle了,接触的越多越感受到自己的渺小!(oracle10g ,Ibatis)

   昨天需要通过数据库查询一组数据,数据中包含一个表中的一条数据、2个String类型的字符串,想通过Oralce的存储过程实现。

ibatis映射配置:

<parameterMap id="parameterDJRYID" class="java.util.HashMap" >    

<parameter property="v_ryid" jdbcType="INTEGER" javaType="java.lang.Integer" mode="IN"/>  //存储过程传入参数

        

<parameter property="PYR_IDS" jdbcType="VARCHAR" javaType="java.lang.String" mode="OUT" />  //存储过程传出参数

<parameter property="PYR_XMS" jdbcType="VARCHAR" javaType="java.lang.String" mode="OUT"/>  //存储过程传出参数

<parameter property="MY_CUR" jdbcType="ORACLECURSOR"  javaType="java.sql.ResultSet" mode="OUT"/>    //存储过程传出参数  

</parameterMap>    

<procedure id="P_DJ_GETRYANDPYRBYRYID"  parameterMap="parameterDJRYID"  resultClass="java.util.HashMap">    

{call P_DJ_GETRYANDPYRBYRYID(?)}    //我的存储过程

</procedure>

Service类调用Ibatis的代码:

Map paramMap = new HashMap();

        paramMap.put("v_ryid", primaryKey);   

        

        List <DjRy> list = DBUtil.getObjectList("T_Dj_Ry.P_DJ_GETRYANDPYRBYRYID", paramMap);   //这个是我们自己封装的工具,主要操作Ibatis,这里可以看成Ibatis查询并返回List结果。

        

        Map<String, Object> map = new HashMap<String, Object>();  

map.put("PYR_IDS", paramMap.get("PYR_IDS"));    //传回的两个参数

map.put("PYR_XMS", paramMap.get("PYR_XMS"));  

map.put("MY_CUR", list);

 

至于我的存储过程就不写出来了,没什么需要特殊写明的,只是数据库的一些关联查询,比较麻烦,就不贴出来了。

 

运行起来后,没成功。。。。

提示的错误信息要求检查输出类型:

--- Check the output parameters (register output parameters failed).  

--- Cause: java.sql.SQLException: 无效的列类型

 

在Google上百度了一下,大部分的人问题的原因都是在Ibatis映射配置时,传入传出的参数中jdbcType与JavaType的类型不正确,可是我多番验证,我的类型是正确的。同时我将传出的参数一个个的减少,直到没有传出参数才能正常运行。真的郁闷了。。。。

经过几个小时的纠结,终于发现问题的所在了。

 

在Ibatis映射配置中,当我调用存储过程中,需要使用?进行参数的占位符,而这个参数不能只写入参,还要写出参。。。。

也就是说,我的Ibatis映射配置中调用存储过程的代码应该这样写:

{call P_DJ_GETRYANDPYRBYRYID(?,?,?,?)}    

欲哭无泪啊!!!!

 

这样程序终于运行起来了,生活还要继续,问题还要继续产生啊!

 

现在是能够在数据库端将数据返回了,返回的结果是2个String类型的字符串,一个结果集。现在我要实现的效果是将结果集给一个list<DjRy>(DjRy是我的Javabean类),那2个字符串就不用理会了。

可是我怎么给,DjRy这个类都不接受!出错了。。。

纠结一番,明白了。

原来我在Ibatis映射配置中,定义的存储过程的返回值为HashMap(下面红色的字体)

<procedure id="P_DJ_GETRYANDPYRBYRYID"  parameterMap="parameterDJRYID"  resultClass="java.util.HashMap">    

{call P_DJ_GETRYANDPYRBYRYID(?,?,?,?)}    //我的存储过程

</procedure>

而这个返回值只是指我3个返回值中结果集的返回值,所以说我返回的结果集是以Hashmap的类型存在的,当我将list中的每一个元素给javabean时,就会发生类型转换错误。

此处需要将定义存储过程的代码改为:

<procedure id="P_DJ_GETRYANDPYRBYRYID"  parameterMap="parameterDJRYID"  resultMap="DjRyResult">    

{call P_DJ_GETRYANDPYRBYRYID(?,?,?,?)}    

</procedure>

DjRyResult就是我的Ibatis中针对DjRy定义的resultMap。这样我就可以将返回的结果集传递给DjRy的List中进行遍历了。

 

还有我的paramMap中在数据库操作之前需要将参数存入,在操作数据库之后,paramMap中会存放返回值中非结果集的参数(包括入参、出参),而在ibatis中定义的出参MY_CUR其实在paramMap中是null值,而list中存放的却是我的结果集返回值。所以在获取返回的参数时,才会按照下面的方式进行:

map.put("PYR_IDS", paramMap.get("PYR_IDS"));    //传回的两个参数

map.put("PYR_XMS", paramMap.get("PYR_XMS"));  

map.put("MY_CUR", list);

这样也产生了新的问题,当我们在开发过程中,如果要返回2个结果集(或者说存储过程中,要返回2个游标),又要怎么处理呢?这个还真没想到!谁要是知道,互相交流一下啊!

 

真不容易啊,就这些弄了一天,落后就要折腾啊!

本文出自 “Key-Value” 博客,请务必保留此出处http://keyvalue.blog.51cto.com/1475446/450113

分享至
更多
一键收藏,随时查看,分享好友!
lee_json、longlonglong_4
2人
了这篇文章
类别:数据库技术圈()┆阅读()┆评论() ┆ 推送到技术圈返回首页

文章评论

 
2010-12-14 12:47:27
娟用上存储过程了,嗯!
不错!!!
接触的越多,进步就越大,好好努力吧!前面还有很多新鲜东西等着你呢!
有空我们交流交流一下。
顺便问下忙不忙,明天有私活干不?项目以万元为单位计算的,不是小网站。

2010-12-14 12:48:26
娟用上存储过程了,嗯!
不错!!!
接触的越多,进步就越大,好好努力吧!前面还有很多新鲜东西等着你呢!
有空我们交流交流一下。
顺便问下忙不忙,明年有私活干不?项目以万元为单位计算的,不是小网站。(修正一下,不是明天,是明年)
博主回复:
2010-12-16 09:10:06
我现在又回归小弟了 唯一不同的是接触的面不同了
等我学好了 在忙别的吧 现在觉得会的太少
看明年什么时候做 要是觉得自己掌握的差不多了 就考虑一下 嘿嘿

2011-04-25 08:47:44
一个过程不可能同时返回两个游标
博主回复:
2011-04-25 14:03:45
从返回值来看也不太可能会返回2个游标,因为刚开始学习,不太确定。担心自己是个井底蛙。
谢谢指教!O(∩_∩)O

2012-04-27 09:56:13
一个过程是可以返回两个游标的。我用java代码可以获取到,但是整合在ibatis中就不会了,最近也在到处寻找资料。

2012-04-27 09:56:45
哎...

 

发表评论            

【技术门诊】专家解析:软考重点难点及应试技巧
昵  称:
登录  快速注册
验证码:

请点击后输入验证码博客过2级,无需填写验证码

内  容: