从java调用oracle存储过程时在mybatis mapper中映射多个out参数

Posted

技术标签:

【中文标题】从java调用oracle存储过程时在mybatis mapper中映射多个out参数【英文标题】:Mapping multiple out params in mybatis mapper when calling an oracle stored procedure from java 【发布时间】:2019-03-27 18:54:28 【问题描述】:

问题是这样的,我想从java调用一个存储过程,使用mybatis/ibatis,这个过程有多个OUT参数,正好7个,其中2个是数字,另外5个Varchars,加上一个IN Number参数

上下文中有一个巨大的限制,即没有模型,只有映射和列表,但如果需要,我们可以在调用过程时例外。另外,解决方案必须在java中完成,没有使用xml。

我有一个 springboot 应用程序,有一个 rest 服务,它调用一个服务 bean,它调用映射器接口,该接口定义了对我正在尝试执行的过程的调用。

到目前为止,我已经尝试在映射器接口中将结果映射到 Object、List、Maps,使用 @Result 尝试逐字段映射到特定的结果类,但是一切都失败了…… mybatis 似乎执行过程没有错误,但遗憾的是没有返回任何内容。

我正在发布我的最新状态,其中包括尝试将结果映射到自定义类,它似乎执行了该过程,但返回了 null

//custom class
public class ProcClass 
    Integer p_tipo_cliente;
    Integer p_codigo_cliente;
    String p_nombre_cliente;
    String p_cuit_cliente;
    String p_cuit_rp;
    String p_razon_social_rp;
    String p_domicilio;

// plus constructor, getters and setters


//Service method 
public ProcClass callProcedure(String param)
        return asociadoMapper.callProcedure(
                Integer.getInteger(param),0,0,
                "",",","","","");
    


//Mapper interface

@Repository
public interface AsociadoMapper extends Mapper 


    @Select(value = AsociadoQueries.getDocumentoAsociadoCall)
    @Options(statementType = StatementType.CALLABLE)
    @Results(value = 
            @org.apache.ibatis.annotations.Result
                    (property = "p_tipo_cliente", column = "p_tipo_cliente"),
            @org.apache.ibatis.annotations.Result
                    (property = "p_codigo_cliente", column = "p_codigo_cliente"),
            @org.apache.ibatis.annotations.Result
                    (property = "p_nombre_cliente", column = "p_nombre_cliente"),
            @org.apache.ibatis.annotations.Result
                    (property = "p_cuit_cliente", column = "p_cuit_cliente"),
            @org.apache.ibatis.annotations.Result
                    (property = "p_cuit_rp", column = "p_cuit_rp"),
            @org.apache.ibatis.annotations.Result
                    (property = "p_razon_social_rp", column = "p_razon_social_rp"),
            @org.apache.ibatis.annotations.Result
                    (property = "p_domicilio", column = "p_domicilio"),
    )
    ProcClass callProcedure(Integer p_id_grupo_familiar,
                            Integer p_tipo_cliente,
                            Integer p_codigo_cliente,
                            String p_nombre_cliente,
                            String p_cuit_cliente,
                            String p_cuit_rp,
                            String p_razon_social_rp,
                            String p_domicilio
                                     );

//Util class

public class AsociadoQueries 


    public static final String getDocumentoAsociadoCall = " CALL consultas_generales.get_detalle_cliente_gf(" +
            "#p_id_grupo_familiar, mode=IN, jdbcType=INTEGER," +
            "#p_tipo_cliente, mode=OUT, jdbcType=INTEGER,,"+
            "#p_codigo_cliente,  jdbcType=INTEGER,"+
            "#p_nombre_cliente,  jdbcType=VARCHAR,"+
            "#p_cuit_cliente,  jdbcType=VARCHAR,"+
            "#p_cuit_rp,  jdbcType=VARCHAR,"+
            "#p_razon_social_rp,  jdbcType=VARCHAR,"+
            "#p_domicilio, jdbcType=VARCHAR"+
            ")";


// Pom related dependencies

<!-- mysql -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.0</version>
        </dependency>


        <!-- https://mvnrepository.com/artifact/org.mybatis.dynamic-sql/mybatis-dynamic-sql -->
        <dependency>
            <groupId>org.mybatis.dynamic-sql</groupId>
            <artifactId>mybatis-dynamic-sql</artifactId>
            <version>1.1.0</version>
        </dependency>

预期的结果很简单,要么返回一个列表、映射或一个包含过程返回的 OUT 参数值的自定义类,现在,我得到的只是 null 或空列表......

【问题讨论】:

【参考方案1】:

哦,好吧,我只是设法弄明白了,我想我必须自己回答,以防它对其他人有帮助...,结果我终于设法通过仅发送 1 个地图作为参数来获取输出参数,并且之前在服务方法中设置 IN 值...此外,映射器现在返回 void,这意味着 mybatis 正在将所有额外的输出参数动态添加到映射中。我也对调用语句做了一些更改,可能那里也有错误?

代码是这样结束的:

    //service call
    public Map<String, Object> callProcedure(String param)

            Map<String, Object> map = new HashMap<String, Object>();
            Integer privilegesCount = 0;
            map.put("p_id_grupo_familiar", Integer.valueOf(param));
            asociadoMapper.callProcedure(map);

            return map;
        
    //mapper
        @Select(value = AsociadoQueries.getDocumentoAsociadoCall)
        @Options(statementType = StatementType.CALLABLE)
        void callProcedure(Map<String,Object> params);

// Call statement

public static final String getDocumentoAsociadoCall = " CALL consultas_generales.get_detalle_cliente_gf(" +
            "#p_id_grupo_familiar,  jdbcType=NUMERIC ,javaType=java.lang.Integer ,mode=IN," +
            "#p_tipo_cliente, jdbcType=NUMERIC,javaType=java.lang.Integer ,mode=OUT,,"+
            "#p_codigo_cliente,  jdbcType=NUMERIC ,javaType=java.lang.Integer ,mode=OUT,"+
            "#p_nombre_cliente,  jdbcType=VARCHAR ,javaType=java.lang.String ,mode=OUT,"+
            "#p_cuit_cliente,  jdbcType=VARCHAR ,javaType=java.lang.String ,mode=OUT,"+
            "#p_cuit_rp,  jdbcType=VARCHAR ,javaType=java.lang.String ,mode=OUT,"+
            "#p_razon_social_rp,  jdbcType=VARCHAR ,javaType=java.lang.String ,mode=OUT,"+
            "#p_domicilio, jdbcType=VARCHAR ,javaType=java.lang.String ,mode=OUT"+
            ")";

【讨论】:

以上是关于从java调用oracle存储过程时在mybatis mapper中映射多个out参数的主要内容,如果未能解决你的问题,请参考以下文章

最近几天一直在搞Mybatis调用存储过程的问题,用<select>标签写的那种!然后用Java里写调用函数

用mybatis做oracle的储存过程

MyBatis调用oracle存储过程

mybatis调用Oracle存储过程

Oracle DBMS 能否从 Java 存储过程调用返回 Java 对象?

从 Java 调用带有数组输出参数的 Oracle 存储过程