使用MyBatis / Spring执行Oracle存储过程并将结果解析为POJO

时间:2016-06-02 00:45:13

标签: oracle stored-procedures mybatis spring-mybatis

我尝试执行Oracle存储过程,并使用注释(即不是XML)将结果映射到POJO,使用mybatis / spring。存储过程的输入/输出是:

public class MyRecord {
    private String output;
    private Integer count;
    // getters and setters...
}

POJO看起来像这样:

@Select(value= "{ CALL my_user.some_package.my_proc('${input}') }")
@Options(statementType = StatementType.CALLABLE)
@ResultType(MyRecord.class)
@Results({
                @Result(property="output", column="P_OUTPUT"),
                @Result(property="count", column="P_COUNT"),
         })
MyRecord parseMyInput(@Param("input") String input);

this example中的代码段,表示它适用于Oracle,对我来说非常适合MySQL存储过程。但是,当我尝试对Oracle存储过程执行以下操作时:

bad SQL grammar []; nested exception is java.sql.SQLException: ORA-06550
PLS-00306: wrong number or types of arguments in call to 'my_proc'
PL/SQL: Statement ignored

...它引发了以下错误:

VARCHAR2

从错误消息中,听起来传递给函数的字符串可能与Oracle的(12345)不兼容,或者我以某种方式发送多个参数。顺便提一下,我传递给函数的字符串是public void other(int counter)

你能看出我做错了吗?

1 个答案:

答案 0 :(得分:1)

@Jorge是对的。必须使用输入参数实例化POJO:

public class MyRecord {
    private String input;
    private String output;
    private Integer count;
    // getters and setters...
}

然后设置POJO的输入参数并调用服务:

    MyRecord myRecord = new myRecord();
    myRecord.setInput("myInput");

    dbMapperOracle.parseMyInput(myRecord);

服务调用映射器,传递包含输入(已设置)和输出参数(此时为空)的变量的POJO:

public class DbServiceOracle {

    @Autowired
    @Qualifier("dataSourceOracle")
    private DbMapperOracle dbMapperOracle;

    public MyRecord parseMyInput(MyRecord params){
        dbMapperOracle.parseMyInput(params);
        return params;
    }
}

映射器将存储过程返回的结果映射到POJO:

@Select(value= "{ CALL my_user.some_package.my_proc(" +
        "#{input,   mode=IN,  javaType = java.lang.String,  jdbcType=VARCHAR}, " +
        "#{output,  mode=OUT, javaType = java.lang.String,  jdbcType=VARCHAR}, " +
        "#{count,   mode=OUT, javaType = java.lang.Integer, jdbcType=NUMERIC}, "
        ") }")
@Options(statementType = StatementType.CALLABLE)
@ResultType(MyRecord.class)
@Results({
                @Result(property="input", column="P_INPUT"),
                @Result(property="output", column="P_OUTPUT"),
                @Result(property="count", column="P_COUNT"),
        })
MyRecord parseMyInput(MyRecord params);

感谢Sanjay Kumar,他将a more complete example放入他的GitHub帐户。