问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

ibatis 怎么返回oracle游标

发布网友 发布时间:2022-04-21 19:10

我来回答

3个回答

热心网友 时间:2022-04-09 07:37

问题总结:

1.index by表不能存储在数据库中的type中,故选择嵌套表。

2.ibatis不支持oracle的复合数据类型的返回。(个人理解)

3.替代方案:用返回oracle游标来代替复合数据类型。ibatis能接受oracle游标类型。

注意此处是ibatis2.3

部分代码:

1.java

复制代码
1 private Map<String,Object> userStateResult(Users users)throws Exception{
2 Map<String,Object> param = new HashMap<String,Object>();
3 param.put("PRM_USERID", users.getUserid().toString());
4 param.put("PRM_OBJECTS", null);
5 param.put("PRM_TAGS", null);
6 param.put("PRM_APPCODE", null);
7 param.put("PRM_ERRMSG", null);
8 getDao().queryForList("user.prc_user_index",param);
9 if(Constant.SUCCESS.equals(param.get("PRM_APPCODE"))){
10 return param;
11 }else{
12 return null;
13 }
14 }
复制代码
返回值(包括游标的返回值)都在param这个map中

2.ibatis代码:

复制代码
1 <parameterMap class="java.util.Map" id="UserIndexParam">
2 <parameter property="PRM_USERID" javaType="java.lang.String"
3 jdbcType="VARCHAR" mode="IN" />
4 <parameter property="PRM_OBJECTS" javaType="java.sql.ResultSet"
5 jdbcType="ORACLECURSOR" mode="OUT" resultMap="ref_object" />
6 <parameter property="PRM_TAGS" javaType="java.sql.ResultSet"
7 jdbcType="ORACLECURSOR" mode="OUT" resultMap="ref_tag" />
8 <parameter property="PRM_APPCODE" javaType="java.lang.String"
9 jdbcType="VARCHAR" mode="OUT" />
10 <parameter property="PRM_ERRMSG" javaType="java.lang.String"
11 jdbcType="VARCHAR" mode="OUT" />
12 </parameterMap>
13 ---------------------------------------------------------------------------------
14 <resultMap id="ref_tag" class="com.diy.tag.entity.Tag">
15 <result column="tagid" jdbcType="VARCHAR" property="tagid" />
16 <result column="tagname" jdbcType="VARCHAR" property="name" />
17 </resultMap>
18
19 <resultMap class="com.diy.comm.cursorHandler.ObjectHandler" id="ref_object">
20 <result column="OBJECTID" jdbcType="DECIMAL" property="objectid" />
21 <result column="OWNERID" jdbcType="DECIMAL" property="ownerid" />
22 <result column="DBUSID" jdbcType="DECIMAL" property="dbusid" />
23 <result column="DUSERSID" jdbcType="DECIMAL" property="sersid" />
24 <result column="TAGID" jdbcType="VARCHAR" property="tagid" />
25 <result column="USERNAME" jdbcType="VARCHAR" property="username" />
26 <result column="OBJNAME" jdbcType="VARCHAR" property="objname" />
27 <result column="LOVENUM" jdbcType="DECIMAL" property="lovenum" />
28 <result column="INRUDUCTION" jdbcType="VARCHAR" property="inruction" />
29 <result column="CATAGROY" jdbcType="DECIMAL" property="catagroy" />
30 <result column="IMAGEPATH" jdbcType="VARCHAR" property="imagepath" />
31 </resultMap>
32 ---------------------------------------------------------------------------
33 <procere id="prc_user_index" parameterMap="UserIndexParam">
34 {call
35 PKG_USER.PRC_USER_INDEXVIEW(?,?,?,?,?)}
36 </procere>
复制代码
有一篇文章写的很好:大家可以参考一下http://blog.sina.com.cn/s/blog_80c111410100vgsh.html

但是对于本问题没有用ibatis的TypeHandler。

因为存储过程调试可以返回游标数据,但是ibatis接受的到全部是null。不知道原因,有知道的朋友可以留言一下。

我个人猜测可能是ibatis版本问题。

3.存储过程代码(部分):

复制代码
--对象类型
CREATE OR REPLACE TYPE TAGS_INFO IS object
(
TAGID number,
TAGNAME varchar2(200)
)
--嵌套表
CREATE OR REPLACE TYPE table_tag IS TABLE OF TAGS_INFO
注意对象和嵌套表都要放在全局的。不能定义在包体中
--兴趣游标
TYPE TAGCURSOR IS REF CURSOR;
--东西游标
TYPE OBJECTCURSOR IS REF CURSOR;--这个定义在包体中
------------------------------------------------------------------------
PROCEDURE PRC_USER_INDEXVIEW(PRM_USERID IN VARCHAR2,
PRM_OBJECTS OUT OBJECTCURSOR,
PRM_TAGS OUT TAGCURSOR,
PRM_APPCODE OUT VARCHAR2,
PRM_ERRMSG OUT VARCHAR2) IS
N_FLAG NUMBER;
VAR_FIRSTTAG VARCHAR2(100);
VAR_DUSERID VARCHAR2(100);
INDEX_TAGS TABLE_TAG;

--用户兴趣标签
CURSOR CUR_USERTAG IS
SELECT C.TAGID, C.NAME
FROM USERSDETIAL A, TAGRELATION B, TAG C
WHERE A.DUSERSID = B.DUSERSID
AND B.TAGID = C.TAGID
AND A.DUSERSID = VAR_DUSERID;
--公共兴趣标签
CURSOR CUR_USERPUB IS
SELECT T.*
FROM (SELECT ROWNUM AS RNUM,
COUNT(A.DUSERSID) AS CNUM,
B.TAGID,
B.NAME
FROM TAGRELATION A, TAG B
WHERE A.TAGID = B.TAGID
GROUP BY A.DUSERSID, B.TAGID, B.NAME, ROWNUM) T
WHERE RNUM <= 8
ORDER BY T.CNUM DESC;
--object
/*CURSOR CUR_OBJ(VAR_TAGID VARCHAR2) IS
SELECT ROWNUM AS RN, A.*
FROM OBJECT A
WHERE trim(A.TAGID) = VAR_TAGID
AND ROWNUM < 30;*/

REC_USERTAG CUR_USERTAG%ROWTYPE;
REC_USERPUB CUR_USERPUB%ROWTYPE;
--REC_OBJ OBJECT%ROWTYPE;
BEGIN
PRM_APPCODE := PKG_COMM.DEF_OK;
PRM_ERRMSG := '';

IF PRM_USERID IS NULL THEN
PRM_APPCODE := PKG_COMM.DEF_ERR;
PRM_ERRMSG := '参数未定义';
RETURN;
END IF;
--用户详细ID是否存在
SELECT B.DUSERSID
INTO VAR_DUSERID
FROM USERS A, USERSDETIAL B
WHERE A.USERID = B.USERSID
AND A.USERID = PRM_USERID;
IF VAR_DUSERID IS NULL THEN
PRM_APPCODE := PKG_COMM.DEF_ERR;
PRM_ERRMSG := '参数无效';
RETURN;
END IF;
--1.判断是否为有效用户
SELECT NVL(A.FLAG, 1)
INTO N_FLAG
FROM USERS A, USERSDETIAL B
WHERE A.USERID = B.USERSID
AND B.DUSERSID = VAR_DUSERID;

IF N_FLAG = 1 THEN
PRM_APPCODE := PKG_COMM.DEF_ERR;
PRM_ERRMSG := '用户已被禁止登录';
RETURN;
END IF;

--2.判断用户是否有兴趣tag

FOR REC_USERTAG IN CUR_USERTAG LOOP
INDEX_TAGS := TABLE_TAG();
IF CUR_USERTAG%ROWCOUNT = 0 THEN
--获取公共兴趣游标
FOR REC_USERPUB IN CUR_USERPUB LOOP
INDEX_TAGS.EXTEND;
IF CUR_USERPUB%ROWCOUNT = 1 THEN
VAR_FIRSTTAG := REC_USERPUB.TAGID;
END IF;
INDEX_TAGS(CUR_USERPUB%ROWCOUNT) := TAGS_INFO(REC_USERPUB.TAGID,
REC_USERPUB.NAME);
END LOOP;
ELSIF CUR_USERTAG%ROWCOUNT = 1 THEN
VAR_FIRSTTAG := REC_USERTAG.TAGID;
END IF;
INDEX_TAGS.EXTEND;
INDEX_TAGS(CUR_USERTAG%ROWCOUNT) := TAGS_INFO(REC_USERTAG.TAGID,
REC_USERTAG.NAME);
--index_tags(CUR_USERTAG%ROWCOUNT).TAGNAME := REC_USERTAG.NAME;

END LOOP;

IF INDEX_TAGS.COUNT <> 0 THEN
/* --3. 取出object
FOR REC_OBJ IN CUR_OBJ(VAR_FIRSTTAG) LOOP
PRM_OBJECTS(CUR_OBJ%ROWCOUNT).OWNERID := REC_OBJ.OWNERID;
PRM_OBJECTS(CUR_OBJ%ROWCOUNT).OBJECTID := REC_OBJ.OBJECTID;
PRM_OBJECTS(CUR_OBJ%ROWCOUNT).DBUSID := REC_OBJ.DBUSID;
PRM_OBJECTS(CUR_OBJ%ROWCOUNT).DUSERSID := REC_OBJ.DUSERSID;
PRM_OBJECTS(CUR_OBJ%ROWCOUNT).TAGID := REC_OBJ.TAGID;
PRM_OBJECTS(CUR_OBJ%ROWCOUNT).LOVENUM := REC_OBJ.LOVENUM;
PRM_OBJECTS(CUR_OBJ%ROWCOUNT).INRUDUCTION := REC_OBJ.INRUDUCTION;
PRM_OBJECTS(CUR_OBJ%ROWCOUNT).CATAGROY := REC_OBJ.CATAGROY;
PRM_OBJECTS(CUR_OBJ%ROWCOUNT).Imagepath := REC_OBJ.Imagepath;

END LOOP;*/
--返回东西游标
OPEN PRM_OBJECTS FOR
SELECT ROWNUM AS RN, A.*, B.USERNAME
FROM OBJECT A, USERSDETIAL B
WHERE A.OWNERID = B.DUSERSID
AND TRIM(A.TAGID) = VAR_FIRSTTAG
AND ROWNUM < 30;

END IF;
--tag游标
OPEN PRM_TAGS FOR
SELECT * FROM TABLE(CAST(INDEX_TAGS AS TABLE_TAG));

EXCEPTION
WHEN OTHERS THEN
PRM_APPCODE := PKG_COMM.DEF_ERR;
PRM_ERRMSG := '获取主界面数据失败' || '错误原因:' || PRM_ERRMSG || '-' || SQLERRM ||
'错误行数:' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE();
END;
---注意:a.返回游标的用open for 方法,不用关心游标的关闭。它是自动关闭的。原因:调试把游标返回值点几下,你就回发现。
b.如果报错CURSOR IS CLOESD的话,说明游标里面没有数据。所以open for 必须保证有select中有数据
c.嵌套表这里要用类似与java的构造方法写,如上
如果写成类似于java中new对象后,用set方法给嵌套表赋值的,会报错未能未能初始化的结果集。

热心网友 时间:2022-04-09 08:55

ibatis中返回oracle游标的写法:
sqlMap.xml配置:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd" >
<sqlMap namespace="KOMUNIKA_REPORT">
<resultMap id="BaseResultMap" class="javaapplication4.StockAreaAndWarehouse" >
<result column="PRODUCT_CODE" property="proctCode" />
<result column="PRODUCT_NAME" property="proctName" />
<result column="INCOMING" property="incoming" />
<result column="UNIT_SOLD" property="unitSold" />
<result column="TOTAL_STOCK" property="totalStock" />
</resultMap>
<parameterMap id="resultMap" class="java.util.Map">
<parameter property="result" javaType="java.sql.ResultSet" jdbcType="ORACLECURSOR" mode="OUT"/>
</parameterMap>
<procere id="selectStockAreaAndWarehouse"
parameterMap="resultMap"
resultMap="BaseResultMap"
>
{ call KOMUNIKA.LP_STOCK_AREA_WAREHOUSE(?) }
</procere>
</sqlMap>

应用中的调用:
package javaapplication4;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import java.io.Reader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
*
* @author ifnu<mailto:ifnubima@gmail.com>
*/
public class Main {
public static void main(String[] args) throws Exception {
String resource;
Reader reader;
List list;
SqlMapClient sqlMap;
resource = "javaapplication4/ibatis.xml";
reader = Resources.getResourceAsReader (resource);
sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
Map map = new HashMap();
// use queryForList because the procere map defines a resultmap
// for the statement
list = sqlMap.queryForList("KOMUNIKA_REPORT.selectStockAreaAndWarehouse", map);
System.out.println(list);
}
}

热心网友 时间:2022-04-09 10:30

ibatis和Mybatis对存储过程和函数函数的调用的配置Xml是不一样的,以下是针对Mybatis 3.2的环境进行操作的。
第一步配置Mapper的xml内容

<mapper namespace="com.rrtong.rrt.auto..SelfStatisticDataDao">
<resultMap id="SelfStatisticData" type="SelfStatisticData">
<id column="name" property="name" />
<result column="count" property="count"/>
</resultMap>

<select id="getSelfStatisticData" parameterType="HashMap" statementType="CALLABLE" >
{#{result,mode=OUT,jdbcType=CURSOR, resultMap=SelfStatisticData} = call PKG_RRT_SelfStatics.Fn_GetSelfStatData(#{userCode,jdbcType=VARCHAR,mode=IN}) }
</select>
</mapper>
说明:1、result对应的是oracle自定义函数返回的游标; 2、映射对象resultMap对应的是SelfStaticData; 3、userCode为传入参数

JAVA中如何得到该游标的数据集呢?下面为调用实例,

@Service
public class SelfStatisticDataServiceImpl implements SelfStatisticDataService{
@Resource
SelfStatisticDataCache selfStatisticDataCache;

public List<?> getSelfStatisticData(String userCode){
List<?> selfStaticDataList = new ArrayList<Map<String,Object>>();
HashMap<String,Object> statMap = new HashMap<String,Object>();
statMap.put("userCode", userCode);
/*设定游标结果写入的变量*/
statMap.put("result", selfStaticDataList);

selfStatisticDataCache.getSelfStatisticData(statMap);
/*获取返回的游标结果集*/
selfStaticDataList = (List<?>) statMap.get("result");

return selfStaticDataList;
}
}
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
你好医生我想问下有时过了性生活后老想上厕所又大小便... 电脑开机按f1怎么开机台式电脑开机需要按F1怎么处理 三者30万标准保费 30万左右的车保险多少钱 30万的车 保险 奥数中的余数问题 石家庄市裕华区小岗上新村前不久传出有传销窝点消息可靠吗? 2019公安部曝光77种涉嫌传销项目 2019年传销诈骗项目名单一览 娱乐圈又曝性骚扰,我想说出她的故事 河北省承德市丰宁县的那一带农村7月底是农忙的时间吗?急~~~ 单位招录了10名新员工,按其应聘成绩排名1到10,并用10个连续的四位自然... 那种短发带有刘海的有好自己打理的发型 那种发型叫... php中$this,static,final,const,self 等几个关... 韩式明星发型,韩剧里面女主的发型有哪些? php中self的真正含义是什么?为什么可以调用父类 ... 男生额头高适合什么发型? php 里面的=&gt;、-&gt; static self class 到底是什么? 宋慧乔机场波波头短发装嫩,你觉得面庞圆润的的人... PHP代码,能详细解释一下每行的意思么?多谢了 php中self与static的区别是什么? 短发怎么扎简单好看图解 韩式丸子头 PHP中this,self和static的区别 韩国街拍发型之沙宣短发波波头造型教你波波头怎么打理 韩系男生短发造型,引领男生发型潮流,你最喜欢哪一个 ob&gt;c和ogc~是什么意思? 湖南人“最喜爱”的露营大山阳明山,有什么著名的风景? 湖南人眼中的南华大学 湖南人怎么看待何炅? 湖南人为什么把槟榔看成是吉祥果? 电视频道这么多,但是有很多不是湖南人都会看芒果... 为什么湖南人长得都那么难看? 韩国女生发型怎样弄 php this和self的区别 python里的self是什麼意思 90后男生流行什么样的发型 如何在Python中使用static,class,abstract方法 短头发梳起来都有什么发型 短发发型绑扎方法大全 高手帮忙解释一下这个说的是什么意思 好看的短发款式有哪些? PHP类中的静态方法返回值,为什么要先判断该静态属... 短头发怎么扎 python 静态方法可以访问类方法吗 韩国男星常用的发型是什么 php static 是什么意思 韩国脸大的女生适合什么发型短发 php 中使用private static 方法名 是什么意思 Python staticmethod 和 classmethod之间的区别 这段php代码是怎么执行的?static的作用是什么?求... 怎么理解这些个关键字啊,public;private;protect;... python 类方法和静态方法的区别 我的电脑硬盘为什么会发出嘟嘟的声音,特别是看在...