MyBatis и хранимая процедура Sybase — набор результатов с безымянными столбцами

Я пытаюсь отобразить набор результатов хранимой процедуры Sybase с помощью MyBatis, но у меня возникают проблемы с неназванными столбцами. Процедура возвращает одну строку с 4 столбцами, 2 из которых вообще не имеют имени:

+---id---|------|-----------|---description---+
     1     name1  surname1        desc1

Файл resultmap .xml выглядит следующим образом (отметьте второй и третий теги результата):

<resultMap id="person" type="foo.Person">
    <result column="id" property="id"/>
    <result column="" property="name"/>
    <result column="" property="surname"/>
    <result column="description" property="description"/>
</resultMap>

У меня нет контроля над кодом хранимой процедуры, поэтому добавление псевдонима к безымянным столбцам невозможно. Проверяя предыдущие версии MyBatis, я увидел, что в прошлом вы могли указать столбецIndex в ResultMap, но теперь он, похоже, больше не доступен. Есть ли какой-то пользовательский обработчик ResultSet, который можно использовать для этого? Или, может быть, какой-то кастомизированный TypeHandler?


person Mauro Henrique Campanha    schedule 31.10.2016    source источник


Ответы (1)


Это обходной путь, но, поскольку вы не можете изменить процедуру в базе данных для добавления имен, я не могу придумать другого способа.

Идея состоит в том, чтобы создать обработчик типа, специфичный для этих полей. Обратите внимание, что если у вас есть одно безымянное поле, вы можете просто отобразить его, используя пустое имя столбца.

Таким образом, в вашем случае карта результатов будет выглядеть так:

<resultMap id="person" type="foo.Person">
    <result column="id" property="id"/>
    <result column="" property="name" typeHandler="foo.PersonNameTypeHandler"/>
    <result column="" property="surname"  typeHandler="foo.PersonSurnameTypeHandler"/>
    <result column="description" property="description"/>
</resultMap>

Драйвер sybase вернет все безымянные столбцы как "".

MyBatis требует, чтобы вы сопоставили свои столбцы с именем существующего столбца, иначе он не будет вызывать обработчик типа. Из-за этого вы не можете создать поддельное имя для этих столбцов, поэтому просто используйте пустое значение для всех безымянных столбцов, в конце пустое имя, если оно важно, просто чтобы заставить MyBatis обработать столбец.

Важная часть находится в обработчике типа, он просто возвращает значение на основе номера столбца, где должно быть «имя»:

public class PersonNameTypeHandler extends BaseTypeHandler<String> {
    ...
    @Override
    public String getNullableResult(ResultSet rs, String columnName) {
        return rs.getString(2);
    }
    ...
}

Важно отметить, что вызываемый метод передает имя столбца, которое в данном случае будет пустым, поэтому просто игнорируйте его и возвращайтесь по индексу столбца.

Кроме того, индекс столбца ResultSet начинается с 1, поэтому в этом случае, чтобы получить имя, которое вы получаете 2, для фамилии реализация будет следующей:

...
return rs.getString(3);
...

Еще одна важная деталь заключается в том, что порядок столбцов должен быть связан с порядком возврата, определенным в вашей процедуре, а не в вашей карте результатов. Если бы столбец «имя» был после столбца «описание» в приведенной выше карте результатов, но возврат процедуры не изменился, индекс, используемый в getString, по-прежнему будет равен 2, а не 4.

Надеюсь это поможет.

person Andre Marques    schedule 07.12.2016