2015-03-23 2 views
1

Я хочу возвращаемый результат оператора выбора ниже, чтобы быть Map<String, Profile>:MyBatis - Возвращение в HashMap

<select id="getLatestProfiles" parameterType="string" resultMap="descProfileMap"> 
    select ml.layerdescription, p1.* 
    from (select max(profile_id) as profile_id 
     from SyncProfiles 
     group by map_layer_id) p2 
    inner join SyncProfiles p1 on p1.profile_id = p2.profile_id 
    inner join maplayers ml on ml.LAYERID = p1.MAP_LAYER_ID 
    where ml.maxsite = #{site} 
</select> 

Я видел этот post, которая отображает строку для пользовательского класса, но ключ был частью обычая класс. В моем запрошенном выше вопросе поле layerdescription не является частью класса Profile, так как я хочу, чтобы класс Profile строго представлял таблицу syncprofiles, а поле layerdescription - в другой таблице.

Мой интерфейс выглядит следующим образом:

public Map<String, Profile> getLatestProfiles(final String site); 

Как следует descProfileMap определить? Я хочу сделать что-то вроде:

<resultMap id="descProfileMap" type="java.util.HashMap"> 
    <id property="key" column="layerdescription" /> 
    <result property="value" javaType="Profile"/> 
</resultMap> 

Но это явно неправильно. Спасибо за вашу помощь!

ответ

0

Достижение этой цели требует 2 шага:

-use ассоциации и вложенную resultMap:

<resultMap type="Profile" id="profileResultMap"> 
    <!-- columns to properties mapping --> 
</resultMap 
<resultMap type="map" id="descProfileMap"> 
    <id property="key" column="layerdescription" /> 
    <association property="value" resultMap="profileResultMap" /> 
</resultMap> 

-add каждая запись на карту с ожидаемой структурой с использованием ResultHandler:

final Map<String, Profile> finalMap = new HashMap<String, Profile>(); 

     ResultHandler handler = new ResultHandler() { 
      @Override 
      public void handleResult(ResultContext resultContext) { 
       Map<String, Object> map = (Map) resultContext.getResultObject(); 
       finalMap.put(map.get("key").toString()), (Profile)map.get("value")); 
      } 
     }; 

session.select("getLatestProfiles", handler); 

Если вы запустите это как есть, ожидайте, что это исключение, скорее всего, будет поднято:

org.apache.ibatis.executor.ExecutorException: Подключенные Заявления с вложенным результатом отображения не могут безопасно использоваться с пользовательской ResultHandler. Используйте safeResultHandlerEnabled = false для обхода этой проверки или убедитесь, что ваш оператор возвращает упорядоченные данные и задает resultOrdered = true.

Тогда следующее предложение, вы можете либо отключить проверку глобально в Mybatis конфигурации:

Согласно документации:

safeResultHandlerEnabled: Позволяет использовать ResultHandler на вложенных заявлений. Если разрешить, установите false. По умолчанию: true.

<settings> 
    <setting name="safeResultHandlerEnabled" value="false"/> 
</settings> 

или указать результат упорядочивается в заявлении:

-сдаточной документации состояния:

resultOrdered Это применимо только для вложенного результата выберите заявления: Если это правда, предполагается, что вложенные результаты: , содержащиеся или сгруппированные вместе, так что, когда новая основная строка результата возвращается , ссылки на предыдущую строку результата wil Я встречаюсь больше. Это позволяет вложенным результатам заполнять гораздо больше памяти. По умолчанию: false.

<select id="getLatestProfiles" parameterType="string" resultMap="descProfileMap" resultOrdered="true"> 

Но я не нашел в любом случае, чтобы указать эту опцию заявления при использовании аннотаций.

Смежные вопросы