#java #mybatis #ibatis #spring-mybatis
Вопрос:
Я новичок в mybatis, и у меня есть вопрос.
У меня есть хранимая процедура 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-картограф в аннотациях?
Комментарии:
1. В настоящее время MyBatis не поддерживает неявный курсор Oracle (т. е.
DBMS_SQL.return_result
). Возможно, вам придется использоватьOUT
параметр для полученияSYS_REFCURSOR
. Вот исполняемая демонстрационная версия. Если вы не используете неявный курсор, пожалуйста, добавьте определение процедуры в вопрос.2. Я добавил процедуру к вопросу
Ответ №1:
Тебе нужно кое-что исправить.
- Вы должны указать
property
атрибуты в результирующей карте.<resultMap id="messageQueryResult" type="de.foo.mapper.MessageValue"> <result column="ID" property="id" /> <result column="NOTE" property="note" /> </resultMap>
- Чтобы получить результат в качестве параметра OUT, методу необходим параметр.
Я используюMap
в качестве параметра. Вы можете использовать POJO со свойствомout
, если хотите.
Кроме того, тип возвращаемого метода должен быть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);
Эта результирующая карта имеет тот же идентификатор, поэтому вы можете удалить <resultMap />
ее из XML-карты, и она должна работать.
Комментарии:
1. большое вам спасибо, это работает на меня. Да
cursorType
означаетSYS_REFCURSOR
, что есть способ определить карту результатов как аннотации Java вместо XML?2. @tine 🙏 Я пропустил ваш последний вопрос. Пожалуйста, ознакомьтесь с обновленным ответом.