Mybatis-возвращает объект, содержащий Hashmap из SELECT
Я работаю с Mybatis-3, и у меня есть следующая ситуация:
У меня есть класс-пользователь, который выглядит следующим образом:
public class User extends GeneralDto {
private String userId;
private String email;
private String firstName;
private String lastName;
private long creationTimestamp;
private long updateTimestamp;
private List<String> tags;
private HashMap<String, String> attributes;
private HashMap<String, String> accounts;
get and set to all + equals + hashcode.
}
Эти две хэш-карты содержат неизвестные ключи и значения типа String (и они доставляют мне много хлопот).
Я уже сопоставил этот класс в таблицы с помощью метода insert. и он сопоставляется в порядке со следующей схемой таблиц:
User (userIdentity, userId, email, firstName, lastName, creationTimestamp, updateTimestamp)
UserAttribute (userIdentity, attributeName, attributeValue, creationTimestamp, updateTimestamp)
UserTag (userIdentity, tagName, creationTimestamp, updateTimestamp)
UserAccount (userIdentity, accountIdentity, role, creationTimestamp, updateTimestamp)
Мне нужно создать метод GET. Метод получает объект UserKey, содержащий идентификатор пользователя который является ключом пользователя. и возвращает экземпляр класса User.
Это оператор SELECT, который объединяет все таблицы и получает соответствующие данные из каждой:
<select id="getUser" parameterType="com.intel.aa.iot.mybatis.UserResultHandler" resultMap="userResultMap" resultOrdered="true">
SELECT
U.userId as userId,
U.email as email,
U.firstName as firstName,
U.lastName as lastName,
U.creationTimestamp as creationTimestamp,
U.updateTimestamp as updateTimestamp,
UT.tagName as tagName,
UAT.attributeName as attributeName,
UAT.attributeValue as attributeValue,
A.accountId as accountId,
UAC.role as role
FROM User U
LEFT OUTER JOIN UserTag UT ON U.userIdentity = UT.userIdentity
LEFT OUTER JOIN UserAttribute UAT ON U.userIdentity = UAT.userIdentity
LEFT OUTER JOIN UserAccount UAC ON U.userIdentity = UAC.userIdentity
LEFT OUTER JOIN ACCOUNTS A ON UAC.accountIdentity = A.accountIdentity
WHERE U.userId = #{userKey.userId}
Этот запрос может возвращать несколько строк из-за объединения, но все строки имеют заданный идентификатор пользователя.
Мой вопрос заключается в том, как я могу сопоставить это в один результат, который является экземпляром класса User.
Я попытался использовать карту результатов, но столкнулся с проблемой с отображением хэш-карты.
Тогда я попробовал используя ResultHandler-возвращающий класс, называемый UserProperties, который содержит каждую хэш-карту в виде двух списков (см. код ниже), но, к сожалению, это не сработало - в конечном итоге сохраняется только одно значение для каждого списка.
Класс свойств пользователя:
public static class UserProperties {
private User user;
private List<String> attributeNames;
private List<String> attributeValues;
private List<String> accountIds;
private List<String> accountRoles;
get and set to all
}
Результирующая Карта:
<resultMap id="userResultMap" type="com.intel.aa.iot.mybatis.UserMapper$UserProperties">
<association property="user" javaType="com.intel.aa.iot.dto.User">
<id property="userId" column="userId"/>
<result property="email" column="email"/>
<result property="firstName" column="firstName"/>
<result property="lastName" column="lastName"/>
<result property="creationTimestamp" column="creationTimestamp"/>
<result property="updateTimestamp" column="updateTimestamp"/>
<collection property="tags" javaType="java.util.ArrayList" column="tagName" ofType="java.lang.String"/>
</association>
<collection property="attributeNames" javaType="java.util.ArrayList" column="attributeName" ofType="java.lang.String"/>
<collection property="attributeValues" javaType="java.util.ArrayList" column="attributeValue" ofType="java.lang.String"/>
<collection property="accountIds" javaType="java.util.ArrayList" column="accountId" ofType="java.lang.String"/>
<collection property="accountRoles" javaType="java.util.ArrayList" column="role" ofType="java.lang.String"/>
</resultMap>
Каковы мои способы работы с этими Hasmaps?
Спасибо!
1 ответ:
У меня самого была такая же проблема в течение последних двух лет, но я еще не нашел идеального решения. В конечном счете проблема заключается в том, что mybatis не позволяет указать ключ хэш - карты-он использует имя свойства результата в качестве ключа.
Два подхода, которые я использовал для решения этой проблемы, далеки от совершенства, но я изложу их здесь, если они вам пригодятся:
Используйте обработчик результатов. Я вижу, ты говоришь, что пробовал это, но получаешь только первое. ценность-есть ли шанс, что вы могли бы поделиться своим кодом? Обработчик результатов вызывается один раз для каждой строки, возвращаемой в запросе, поэтому вы не хотите создавать новый объект каждый раз. Вы хотите создать объект только в том случае, если у вас еще нет объекта, который соответствует идентификатору в этой строке, а затем итеративно построить его на основе следующих строк.
Создайте имена и значения в виде списка хэш-карт, а затем используйте перехватчик select (плагин mybatis) для вызова метода внутри объекта для построения ваши настоящие хэш-карты. Для этого в вашей результирующей карте нужно указать свое имя и значение результата под ассоциацией типа hashmap. Затем Mybatis превратит это в список, который выглядит следующим образом:
[список [хранилище HashMap {"имя_атрибута"=имя1,"attributeValue"=значение1}], [хранилище HashMap {"имя_атрибута"=имя2,"attributeValue"=значение2}]]
Затем вы можете вызвать метод в перехватчике, который повторяет эту хэш-карту, чтобы построить хэш-карту, которую вы хотите.
Ни одно из решений не является хорошенький. Первое решение теряет элегантность отображения результатов, а второе решение загрязняет объект домена. Но если вас интересуют дальнейшие подробности, дайте мне знать, и я добавлю несколько примеров кода.
Comments