java - Mybatis - 从 SELECT 返回包含 Hashmap 的对象

标签 java mysql hashmap mybatis

我正在使用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.
}

这两个 HashMap 包含未知的键和字符串类型的值(它们给我带来了很多麻烦)。

我已经使用插入方法将这个类映射到表中。并且它可以映射到下表方案:

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 对象,该对象包含作为用户 key 的 userId。并返回用户类的一个实例。

这是连接所有表并从每个表中获取相关数据的 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}

由于连接的原因,此查询可能返回多行,但所有行都属于给定的 userId。

我的问题是如何将其映射到一个作为用户类实例的结果中。 我尝试使用结果映射,但在映射 HashMap 时遇到了问题。 然后我尝试使用 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>

处理这些 Hasmap 的方法是什么?

谢谢!

最佳答案

在过去的几年里,我自己也遇到过同样的问题,但我还没有找到理想的解决方案。最终问题是 mybatis 不允许您指定 hashmap 的键 - 它使用结果属性名称作为键。

我为解决此问题而采取的两种方法远非完美,但我将在此处概述它们以防它们对您有用:

  1. 使用结果处理程序。我看到你说你已经尝试过了,但只得到了第一个值——你有机会分享你的代码吗?结果处理程序在查询中返回的每行被调用一次,因此您不想每次都创建一个新对象。只有当您还没有与该行中的 ID 匹配的对象时,您才想创建一个对象,然后根据以下行迭代构建它。

  2. 将名称和值构建为散列图列表,然后使用选择拦截器(mybatis 插件)调用对象内部的方法来构建真正的散列图。为此,在您的结果映射中,您需要在类型 HashMap 的关联下指定您的名称和值结果。然后 Mybatis 会将其转换为如下所示的列表:

    [列表 [Hashmap {"attributeName"=name1,"attributeValue"=value1}], [Hashmap {"attributeName"=name2,"attributeValue"=value2}]]

然后你可以在拦截器中调用一个方法来迭代这个hashmap来构建你想要的hashmap。

这两种解决方案都不漂亮。第一个解决方案失去了结果映射的优雅,第二个解决方案弄脏了您的域对象。但如果您对更多细节感兴趣,请告诉我,我将添加一些代码示例。

关于java - Mybatis - 从 SELECT 返回包含 Hashmap 的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25764169/

相关文章:

java - 将 HashMap 转换为以逗号分隔的字符串

java - 如何从源代码制作 .jar 库

java - IceFaces 将其 CSS 和 JavaScript 资源放在每个页面上,无论它们是否使用 Ice 组件。有办法阻止这个吗?

java - Hibernate 抛出无法删除或更新父行异常

javascript - Ajax卡在beforeSend阶段,不向PHP发送数据

java - 为什么HashMap内部工作辅助变量是int,可以是byte数据类型

java - 为什么这个 HashMap 被作为引用传递

java - 如何根据条件禁用 TestNG 测试

java - Integer.toBinaryString 方法的有符号等效项?

php - 在数据表插件上的 mysql WHERE 子句上使用 GET 方法不起作用