首页 > 解决方案 > 带有游标结果的存储过程的 mybatis 注释配置

问题描述

我是 mybatis 的新手,我有一个问题。
我有一个返回 CURSOR 的 Oracle 存储过程。

我不明白如何编写带有注释的结果集。

如果我试试这个,

@Mapper
public interface Message{

    @Select(value="{ #{OUT,javaType=java.sql.ResultSet,resultMap=messageQueryResult,jdbcType=CURSOR,mode=OUT} = call get_messages() }")
    @Options(statementType = StatementType.CALLABLE)
    @ResultMap("messageQueryResult")
    List<Message> getMessages();
}
<mapper namespace="de.foo.mapper.Message">
    <resultMap id="messageQueryResult" type="de.foo.mapper.MessageValue">
    
            <result column="ID" javaType="java.lang.Long" />
            <result column="NOTE" javaType="java.lang.String" />

    </resultMap>
</mapper>
public class MessageValue{

    private Long id;
    private String note;
}
FUNCTION get_messages
  RETURN cursorType
  IS 
    c_messages  cursorType;
    sqlstring   VARCHAR2(4000);
  BEGIN
    sqlstring :=  'SELECT id, note FROM '||
                             ' vmessage WHERE ID IN ( ' ... ')';                                           

    OPEN cmessage FOR sqlstring;
    RETURN cmessage;
  END get_messages;

我收到一个错误

org.apache.ibatis.reflection.ReflectionException: There is no setter for property named 'OUT' in 'class java.lang.Class'

我究竟做错了什么?是否有可能在注释中编写 XML 映射器?

标签: javamybatisibatisspring-mybatis

解决方案


你需要解决一些问题。

  1. 您必须在结果映射中指定property属性。

    <resultMap id="messageQueryResult" type="de.foo.mapper.MessageValue">
      <result column="ID"  property="id" />
      <result column="NOTE" property="note" />
    </resultMap>
    
  2. 要将结果作为 OUT 参数接收,该方法需要一个参数。
    Map用作参数。out如果您愿意,可以将 POJO 与属性一起使用。
    此外,方法的返回类型应该void并且@ResultMap应该被删除。

    @Select({
      "{ #{OUT,",
      "javaType=java.sql.ResultSet,", 
      "resultMap=messageQueryResult,", 
      "jdbcType=CURSOR,", 
      "mode=OUT} = call get_messages() }" })
    @Options(statementType = StatementType.CALLABLE)
    void getMessages(Map<String, Object> param);
    

执行后,结果将被设置为参数,所以基本上是这样使用它的。

Map<String, Object> param = new HashMap<>();
mapper.getMessages(param);
List<MessageValue> messages = (List<MessageValue>) param.get("OUT");
...

顺便说一句,我认为这cursorType意味着SYS_REFCURSOR


关于您的最后一个问题,可以使用注释@Results@Result(文档在此处)定义结果图。
您的情况有点棘手,因为 MyBatis 在构建结果映射时使用了带注释的方法的返回类型。因此,您可能需要添加另一个映射器方法,而不是注释getMessage()方法,如下所示。

@Results(id = "messageQueryResult", value = {
  @Result(column = "ID", property = "id"),
  @Result(column = "NOTE", property = "note")
})
@Select("select ID, NOTE from vmessage where ID = #{id}")
MessageValue getById(@Param("id") Long id);

此结果映射具有相同的 ID,因此您可以<resultMap />从 XML 映射器中删除它,它应该可以工作。


推荐阅读