myBatis多对多关系

时间:2018-04-18 09:57:08

标签: java sql mapping mybatis

关于我之前关于myBatis中映射的问题,我现在遇到了一个多对多关系中的问题

我有以下对象

//由于隐私问题,我无法发布实际的对象定义和XML

class ObjectA {
     List<Items> items;
     List<Products> products;

     //getters setters
}

class Items {
   int id;
   String description;
   List<Tags> tags;
}

class Tags {
    int id;
    int item_id;
    String tag;
}

SQL涉及使用标签表ON Tags.ITEM_ID = Items.ID

连接Items表

基本上,它返回行并将它们映射到此myBatis

<resultMap id="getObjectA" type="ObjectA">
    <collection property="items" javaType="ArrayList" ofType="Items" resultMap="getItems"/>

     ...

</resultMap>

<resultMap="getItems" type="Items">
    <id property="id" column="ITEMS.id"/>
    <result property="description" column="ITEMS.description"/>
    <collection property="tags" javaType="ArrayList" ofType="Tags" resultMap="getTags"/>
</resultMap>

<resultMap id="getTags" type="Tags">
   <id property="id" column="TAGS.id"/>
   <result property="item_id" column="TAGS.item_id"/>
   <result property="tag" column="TAGS.tag"/>
</resultMap>

从技术上讲,设置工作并返回一个ObjectA,其中包含每个包含标签列表的项目列表。当每个项目只存在一个标签时,映射很好,但是当一个Item包含多个标签时,它会创建多个具有相同ID的项目,每个项目包含一个List,该List仅包含查询结果中的一个Tag。

1 个答案:

答案 0 :(得分:1)

创建父对象的重复项意味着mybatis无法正确识别对象,即<id property="id" column="ITEMS.id"/>无法按预期工作。基本上需要id元素,以便mybatis知道结果集中多行中重复的父记录引用同一个对象。

一个工作选项是确保来自不同表的列具有唯一名称,并在结果映射中使用该唯一名称。

对于您的示例,mapper应如下所示:

<resultMap type="ObjectA" id="objectaMap">
    <id column="id" property="id"/>
    <collection property="items" javaType="ArrayList" ofType="Items" columnPrefix="ITEM_">
        <id column="id" property="id"/>
        <result property="description" column="description"/>
        <collection property="tags" javaType="ArrayList" ofType="Tags" columnPrefix="TAG_">
            <id column="id" property="id"/>
            <result property="tag" column="tag"/>
        </collection>
    </collection>
</resultMap>

<select id="getObjects" resultMap="objectaMap">
    select o.*, i.id as ITEM_ID, i.description as ITEM_DESCRIPTION, t.id as ITEM_TAG_ID, t.tag as ITEM_TAG_TAG
    from objecta o
        join items i on (i.object_id = o.id) 
        join tags t on (t.item_id = i.id)
</select>

请注意items表中的所有列都有ITEM_前缀,而tags表的列是相同的。