使用 MyBatis/Spring 执行 Oracle 存储过程并将结果解析为 POJO
execute Oracle stored procedure using MyBatis/Spring and parse results to a POJO
我正在尝试执行 Oracle 存储过程,并将结果映射到 POJO,mybatis/spring 使用注释(即不是 XML)。存储过程的 inputs/outputs 是:
P_INPUT VARCHAR2 IN
P_OUTPUT VARCHAR2 OUT
P_COUNT BINARY_INTEGER OUT
POJO 看起来像这样:
public class MyRecord {
private String output;
private Integer count;
// getters and setters...
}
this example 中的代码片段说它适用于 Oracle,对我来说非常适合 MySQL 存储过程。但是,当我尝试对 Oracle 存储过程执行以下操作时:
@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);
...它引发了以下错误:
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
从错误消息来看,似乎传递给函数的字符串可能与 Oracle 的 VARCHAR2
不兼容,或者我以某种方式发送了多个参数。顺便说一下,我传递给函数的字符串是 (12345)
.
你能看出我做错了什么吗?
@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 帐户。
我正在尝试执行 Oracle 存储过程,并将结果映射到 POJO,mybatis/spring 使用注释(即不是 XML)。存储过程的 inputs/outputs 是:
P_INPUT VARCHAR2 IN
P_OUTPUT VARCHAR2 OUT
P_COUNT BINARY_INTEGER OUT
POJO 看起来像这样:
public class MyRecord {
private String output;
private Integer count;
// getters and setters...
}
this example 中的代码片段说它适用于 Oracle,对我来说非常适合 MySQL 存储过程。但是,当我尝试对 Oracle 存储过程执行以下操作时:
@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);
...它引发了以下错误:
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
从错误消息来看,似乎传递给函数的字符串可能与 Oracle 的 VARCHAR2
不兼容,或者我以某种方式发送了多个参数。顺便说一下,我传递给函数的字符串是 (12345)
.
你能看出我做错了什么吗?
@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 帐户。