2014-09-10 36 views
2
包含HashMap對象

我用的MyBatis-3的工作,我有以下情況:的MyBatis - 返回從SELECT

我有類 - 用戶看起來如下:

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包含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方法。該方法接收包含作爲用戶密鑰的userId的UserKey對象。並返回用戶類的一個實例。

這是連接所有表,並會從每個相關數據的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。

我的問題是如何將其映射到一個用戶類的實例的結果。 我嘗試使用結果映射,但遇到了映射散列映射的問題。 然後我嘗試使用ResultHandler - 返回一個名爲UserProperties的類,其中包含每個hashmap作爲兩個列表(請參閱下面的代碼),但不幸的是它並不工作 - 每個列表最終只保存一個值。

的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:

<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方式?

謝謝!

回答

3

我在過去幾年裏自己也有過這個相同的問題,但我還沒有找到理想的解決方案。最終問題是,mybatis不允許你指定hashmap的鍵 - 它使用result屬性名作爲鍵。

我已經採取瞭解決此兩種方法是遠非完美,但我會在這裏勾勒出的情況下他們他們對您有用:

  1. 使用結果處理程序。我看到你說你已經試過這個,但只獲得第一個價值 - 你有可能分享你的代碼嗎?結果處理程序在查詢中返回的每行被調用一次,因此您不希望每次都創建一個新對象。只有當您沒有與此行中的ID相匹配的對象時纔想創建對象,然後基於以下行迭代地構建它。

  2. 構建名稱和值作爲hashmaps列表,然後使用選擇攔截器(mybatis插件)來調用對象內的方法來構造真正的hashmaps。爲此,在結果圖中,您需要在類型hashmap的關聯下指定您的名稱和值結果。然後Mybatis會將它變成如下列表:

    [List [Hashmap {「attributeName」= name1,「attributeValue」= value1}],[Hashmap {「attributeName」= name2,「attributeValue」= value2} ]]

然後,您可以在攔截器中調用一個方法來迭代這個散列表來構建你想要的散列表。

兩個解決方案都不是很漂亮。第一種解決方案失去了結果地圖的優雅,第二種解決方案會污染你的領域對象。但如果您對更多細節感興趣,請告訴我,我將添加一些代碼示例。

+0

感謝你們,我終於使用了UserProperties類,然後在mybatis之外創建了類User的一個實例。正如你所說,這個解決方案不太好或不好。你的第二個建議似乎很有趣,但我必須使用特定的API,所以我不能將散列映射更改爲散列映射列表。 – Yuval 2014-09-14 05:44:35