tutututa
tutututa
2011-12-19 11:46

ibatis调用存储过程入参问题

已采纳

CREATE OR REPLACE TYPE EMP_SALARY_REC AS OBJECT (
EMP_ID NUMBER(5),
EMP_NAME VARCHAR2(255),
START_DATE DATE,
SALARY NUMBER
);
/

CREATE OR REPLACE Type EMP_SALARY_TAB AS TABLE OF EMP_SALARY_REC;
/

next we will create a small package with one single test procedure

CREATE OR REPLACE PACKAGE EMP_SALARY_PKG IS
PROCEDURE GET_EMP_SALARIES(i_array IN EMP_SALARY_TAB,o_array OUT
EMP_SALARY_TAB);
End EMP_SALARY_PKG;
/

用ibatis就不能配置调用吗?


问题补充
niwenbin 写道
SQL Map通过<procedure>元素支持存储过程。下面的例子说明如何使用具有输出参数的存储过程。
<parameterMap id="swapParameters" class="map" >
<parameter property="email1" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
<parameter property="email2" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
</parameterMap>
<procedure id="swapEmailAddresses" parameterMap="swapParameters" >
{call swap_email_address (?, ?)}
</procedure>
调用上面的存储过程将同时互换两个字段(数据库表)和参数对象(Map)中的两个email
地址。如果参数的mode属性设为INOUT或OUT,则参数对象的值被修改。否则保持不变。



参数是自定义的type类型(EMP_SALARY_TAB):
CREATE OR REPLACE TYPE EMP_SALARY_REC AS OBJECT (
EMP_ID NUMBER(5),
EMP_NAME VARCHAR2(255),
START_DATE DATE,
SALARY NUMBER
);
CREATE OR REPLACE Type EMP_SALARY_TAB AS TABLE OF EMP_SALARY_REC;

问题补充
threejin520 写道
Ibatis访问存储过程的配置 zz  2009-10-30 16:35:48|  分类: Java |  标签: |字号大

小 订阅

最近项目里经常需要配置用Ibatis访问存储过程(或函数),多次摸索,发现配置的难点是在于如何配置输入输出参数。现以访问Oracle的存储过程(或函数)举例说明。

一般基本的配置要点如下:

(1)、访问存储过程(或函数)一般以procedure标签来定义statement。

(2)、输入输出的参数需要用parameterMap标签单独定义。

(3)、区分输入输出参数用parameter标签的mode属性来定义,分别为”OUT”和”IN”。

按照是否有返回值,是否使用游标分类说明如下:

第一类,没有返回结果,有输出参数以out标识的过程访问配置样式:

<parameterMap id=”functionPramsMap” class=”map”>

<parameter property=”p1″ jdbcType=”VARCHAR” javaType=”string” mode=”IN”/>

<parameter property=”p2″ jdbcType=”INTEGER” javaType=”int” mode=”IN”/>

<parameter property=”p3″ jdbcType=”INTEGER” javaType=”int” mode=”OUT” />

</parameterMap>

<procedure id=”statementId” parameterMap=”functionPramsMap”>

{call packageName.functionName(?,?,?)}

</procedure>

第二类,有返回结果,有输出参数以out标识的过程访问配置样式:

<parameterMap id=”functionParamsMap” class=”map”>

<parameter property=”p0″ jdbcType=” INTEGER” javaType=”string” mode=”OUT”/>

<parameter property=”p1″ jdbcType=”VARCHAR” javaType=”string” mode=”IN”/>

<parameter property=”p2″ jdbcType=”INTEGER” javaType=”int” mode=”IN”/>

<parameter property=”p3″ jdbcType=”INTEGER” javaType=”int” mode=”OUT” />

</parameterMap>

<procedure id=”statementId” parameterMap=” functionParamsMap”>

{?=call packageName.functionName(?,?,?)}

</procedure>

这里参数p0标识调用过程的返回结果。

第三类,有使用游标的的过程访问配置样式:

<resultMap id=”resultMap” class=”package.ClassA”>

<result property=”property0″ column=”field0″ />

<result property=”property1″ column=”field2″ />

<result property=”property2″ column=”field3″ />

</resultMap>

<parameterMap id=”functionParamsMap” class=”map”>

<parameter property=”p0″ jdbcType=” INTEGER” javaType=”string” mode=”OUT”/>

<parameter property=”p1″ jdbcType=”VARCHAR” javaType=”string” mode=”IN”/>

<parameter property=”p2″ jdbcType=”INTEGER” javaType=”int” mode=”IN”/>

<parameter property=”p3″ jdbcType=”ORACLECURSOR”

javaType=”java.sql.ResultSet” mode=”OUT” resultMap=”resultMap” />

</parameterMap>

<procedure id=”statementId” parameterMap=”functionPramsMap”>

{?=call packageName.functionName(?,?,?)}

</procedure>

这里,关键注意的是p3参数,由于使用的是oracle数据库驱动,所以用jdbcType=”ORACLECURSOR”表示oracle游标,同时由于是游标,所以javaType=”java.sql.ResultSet”。最后必须要给参数p3配置好resultMap属性,以说明游标返回的结果集映射方式,不配置此属性,在代码里来访问结果集是不行的。此时,在Java代码里调用的样式如下:

HashMap<String, Object> params = new HashMap<String, Object>();

params.put(”p1″, p1);

params.put(”p2″, p2);

sqlMapClient.queryForObject(”statementId”, params);

List<ClassA> list = (List<ClassA>) params.get(”p3″);

if (list != null && list.size() > 0) {

return userList.get(0);

}

return null;

第四类,有复杂的参数类型的存储过程:

(1)、对于BLOB或者CLOB,在POJO里的属性都定义为byte[]类型,iBatis配置里跟普通类型参数一样处理;

(2)、实现TypeHandler来自定义类型处理器用户处理复杂的字段;

(3)、对于数据库自定义的数据类型,首先要定义实现了java.sql.SQLData的类Class TypeA。实现getSQLTypeName方法,返回值为数据库的自定义类型名。配置文件里parameter标签的属性如:jdbcType=”TypeB” JavaType=”TypeA”,同时还要写TypeHandlerCallback用于处理jdbcType=”TypeB”的类型。

我现在需要第四类的例子,如何构建ARRAY
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

6条回答

  • YONG141520 YONG141520 10年前

    写一个handler,来解析数据库的自定义类型

    parameterMap 配置

    typeName="LIFEMAN.ANESTEDSTRTABLE"
    typeHandler="com.palic.elis.integration.dao.typehandler.ArrayTypeHandler"
    mode="IN" />
    typeName="LIFEMAN.ANESTEDSTRTABLE"
    typeHandler="com.palic.elis.integration.dao.typehandler.ArrayTypeHandler"
    mode="OUT" />

    ArrayTypeHandler类

    // Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
    // Jad home page: http://kpdus.tripod.com/jad.html
    // Decompiler options: packimports(3) fieldsfirst ansi space
    // Source File Name: ArrayTypeHandler.java

    import com.ibatis.sqlmap.engine.type.BaseTypeHandler;
    import com.ibatis.sqlmap.engine.type.TypeHandler;
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.sql.*;
    import java.util.ArrayList;
    import java.util.List;

    public class ArrayTypeHandler extends BaseTypeHandler
    implements TypeHandler
    {

    public ArrayTypeHandler()
    {
    }
    
    public void setParameter(PreparedStatement preparedstatement, int i, Object obj, String s)
        throws SQLException
    {
        throw new SQLException("不支持此方法 !!");
    }
    
    public Object getResult(ResultSet resultset, String s)
        throws SQLException
    {
        throw new SQLException("不支持此方法 !!");
    }
    
    public Object getResult(ResultSet resultset, int i)
        throws SQLException
    {
        throw new SQLException("不支持此方法 !!");
    }
    
    public Object getResult(CallableStatement callablestatement, int i)
        throws SQLException
    {
        try{
            ArrayList arraylist;
            ResultSet resultset = callablestatement.getArray(i).getResultSet();
            arraylist = new ArrayList();
            while (resultset.next()) 
            {
                java.io.InputStream inputstream = resultset.getBinaryStream(2);
                if (inputstream != null)
                {
                    BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(inputstream, "GBK"));
                    StringBuffer stringbuffer = new StringBuffer();
                    for (String s = null; (s = bufferedreader.readLine()) != null;)
                        stringbuffer.append(s);
    
                    arraylist.add(stringbuffer.toString());
                } else{
                    arraylist.add(null);
                }
            }
            if (callablestatement.wasNull())
                return null;
            return arraylist;
        }catch(Exception exception){        
             throw new SQLException("TypeHandler异常:" + exception.getMessage());
        }
    }
    
    public Object valueOf(String s)
    {
        return null;
    }
    

    }

    点赞 评论 复制链接分享
  • qq1988627 qq1988627 10年前

    [code="java"]

    //输出参数 用的是游标

































    <![CDATA[
    {call MATE_LOCAL_ACTION (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}
    ]]>


    [/code]

    点赞 评论 复制链接分享
  • niwenbin416 niwenbin416 10年前

    SQL Map通过元素支持存储过程。下面的例子说明如何使用具有输出参数的存储过程。





    {call swap_email_address (?, ?)}

    调用上面的存储过程将同时互换两个字段(数据库表)和参数对象(Map)中的两个email
    地址。如果参数的mode属性设为INOUT或OUT,则参数对象的值被修改。否则保持不变。

    点赞 评论 复制链接分享
  • iteye_2218 iteye_2218 10年前

    你可以在程序里面来调用存储

    点赞 评论 复制链接分享
  • iteye_2218 iteye_2218 10年前

    Ibatis访问存储过程的配置 zz 2009-10-30 16:35:48| 分类: Java | 标签: |字号大

    小 订阅

    最近项目里经常需要配置用Ibatis访问存储过程(或函数),多次摸索,发现配置的难点是在于如何配置输入输出参数。现以访问Oracle的存储过程(或函数)举例说明。

    一般基本的配置要点如下:

    (1)、访问存储过程(或函数)一般以procedure标签来定义statement。

    (2)、输入输出的参数需要用parameterMap标签单独定义。

    (3)、区分输入输出参数用parameter标签的mode属性来定义,分别为”OUT”和”IN”。

    按照是否有返回值,是否使用游标分类说明如下:

    第一类,没有返回结果,有输出参数以out标识的过程访问配置样式:

    {call packageName.functionName(?,?,?)}

    第二类,有返回结果,有输出参数以out标识的过程访问配置样式:

    {?=call packageName.functionName(?,?,?)}

    这里参数p0标识调用过程的返回结果。

    第三类,有使用游标的的过程访问配置样式:

    <parameter property=”p3″ jdbcType=”ORACLECURSOR”

    javaType=”java.sql.ResultSet” mode=”OUT” resultMap=”resultMap” />

    {?=call packageName.functionName(?,?,?)}

    这里,关键注意的是p3参数,由于使用的是oracle数据库驱动,所以用jdbcType=”ORACLECURSOR”表示oracle游标,同时由于是游标,所以javaType=”java.sql.ResultSet”。最后必须要给参数p3配置好resultMap属性,以说明游标返回的结果集映射方式,不配置此属性,在代码里来访问结果集是不行的。此时,在Java代码里调用的样式如下:

    HashMap params = new HashMap();

    params.put(”p1″, p1);

    params.put(”p2″, p2);

    sqlMapClient.queryForObject(”statementId”, params);

    List list = (List) params.get(”p3″);

    if (list != null && list.size() > 0) {

    return userList.get(0);

    }

    return null;

    第四类,有复杂的参数类型的存储过程:

    (1)、对于BLOB或者CLOB,在POJO里的属性都定义为byte[]类型,iBatis配置里跟普通类型参数一样处理;

    (2)、实现TypeHandler来自定义类型处理器用户处理复杂的字段;

    (3)、对于数据库自定义的数据类型,首先要定义实现了java.sql.SQLData的类Class TypeA。实现getSQLTypeName方法,返回值为数据库的自定义类型名。配置文件里parameter标签的属性如:jdbcType=”TypeB” JavaType=”TypeA”,同时还要写TypeHandlerCallback用于处理jdbcType=”TypeB”的类型。

    点赞 评论 复制链接分享
  • datamodule datamodule 10年前
    点赞 评论 复制链接分享

相关推荐