Java myBatis是多对多关系

Java myBatis是多对多关系,java,sql,mapping,mybatis,Java,Sql,Mapping,Mybatis,关于我之前关于myBatis中映射的问题,我现在在处理多对多关系时遇到了一个问题 我有以下对象 //由于隐私问题,我无法发布实际的对象定义和XML class ObjectA { List<Items> items; List<Products> products; //getters setters } class Items { int id; String description; List<Tags>

关于我之前关于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;
}
类ObjectA{
清单项目;
列出产品清单;
//吸气剂二传手
}
类别项目{
int-id;
字符串描述;
列出标签;
}
类标记{
int-id;
int item_id;
字符串标签;
}
SQL涉及将Items表与Tags.ITEM_ID=Items.ID上的Tags表连接起来

基本上,它返回行并将它们映射到此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,其中包含一个项目列表,每个项目都包含一个标记列表。当每个项目只有一个标记时,映射就可以了,但当一个项目包含多个标记时,它会创建多个ID相同的项目,每个项目都包含一个列表,其中只包含查询结果中的一个标记。

创建父对象的副本这一事实意味着mybatis无法正确识别对象,也就是说,
不能按预期工作。基本上,需要
id
元素,以便mybatis知道在结果集中多行复制的父记录引用同一对象

一个可行的选择是确保不同表中的列具有唯一名称,并在结果映射中使用该唯一名称

例如,映射器应如下所示:

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

选择o.*,i.id作为项目\ id,i.description作为项目\描述,t.id作为项目\标记\ id,t.TAG作为项目\标记\标记
来自反对
连接i上的项目(i.object\u id=o.id)
连接标签t on(t.item_id=i.id)

请注意,
项目
表中的所有列如何具有
项目
前缀,以及
标记
表的前缀相同。

创建父对象的副本这一事实意味着mybatis无法正确识别对象,即
无法按预期工作。基本上,需要
id
元素,以便mybatis知道在结果集中多行复制的父记录引用同一对象

一个可行的选择是确保不同表中的列具有唯一名称,并在结果映射中使用该唯一名称

例如,映射器应如下所示:

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

选择o.*,i.id作为项目\ id,i.description作为项目\描述,t.id作为项目\标记\ id,t.TAG作为项目\标记\标记
来自反对
连接i上的项目(i.object\u id=o.id)
连接标签t on(t.item_id=i.id)

请注意
表中的所有列如何具有
前缀以及
标记
表的前缀相同。

SQL是什么?需要确保行由相关ID排序。MyBatis使用ID来标识(而不是重复)项。@SQL使用别名时,会观察到每列的正确标签SQL是什么?需要确保行由相关ID排序。MyBatis使用ID来标识(而不是重复)项。@SQL使用别名时,每个列的正确标签都会被观察到。我在表中使用别名,我只是不能在这里包含它。我成功地检索到了值,只是它没有使用多个标记创建多个项,而是使用单个标记创建多个项。我遇到的问题是,它没有使用子对象列表,而是使用单个子对象创建父对象的副本。如果不看到查询,很难判断。我在回答中描述的选项起作用,并使用
标记的列表创建单个
项目
。是的,它是这样工作的,但问题是,ObjectA没有Id。它只是一个包含项目列表和产品列表的对象。My resultMap返回ObjectA,其中包含Select查询中的项目和产品的集合。我们有相同的查询,只是不应该是ObjectA的结果,而应该是项、标记、产品的联接。我在表上使用别名,我只是不能在这里包含它。我成功地检索到了值,只是它没有使用多个标记创建多个项,而是使用单个标记创建多个项。我遇到的问题是,它没有使用子对象列表,而是使用单个子对象创建父对象的副本。如果不看到查询,很难判断。我在回答中描述的选项起作用,并使用
标记的列表创建单个
项目
。是的,它是这样工作的,但问题是,ObjectA没有Id。它只是一个包含项目列表和产品列表的对象。My resultMap返回ObjectA,其中包含Select查询中的项目和产品的集合。我们有相同的查询,只是不应该是ObjectA的结果,而应该是项、标记和产品的连接