Mybatis-3: Use <include> in <resultMap>

Created on 12 Sep 2013  Â·  9Comments  Â·  Source: mybatis/mybatis-3

In mapper.xml, two resultMap include the same content or one resultMap include other resultMap.

enhancement

Most helpful comment

Another option would be if extends supported multiple resultmaps. Then this would be written as:

<resultMap id="InterfaceA" class="my.package.InterfaceA">
  <result property="property1" column="PROPERTY_1" />
</resultMap>
<resultMap id="InterfaceB" class="my.package.InterfaceB">
  <result property="property2" column="PROPERTY_2" />
</resultMap>
<resultMap id="ClassA" class="my.package.ClassA" extends="InterfaceA">
  <constructor>
    <idArg column="ID" />
  </constructor>
</resultMap>
<select id="selectClassA" resultMap="ClassA">
  select
    A.ID,
    A.PROPERTY_1
  from TABLE_A A
</select>
<resultMap id="ClassAB" class="my.package.ClassAB" extends="InterfaceA,InterfaceB">
  <constructor>
    <idArg column="ID" />
  </constructor>
</resultMap>
<select id="selectClassAB" resultMap="ClassAB">
  select
    AB.ID,
    AB.PROPERTY_1,
    AB.PROPERTY_2
  from TABLE_AB AB
</select>

All 9 comments

is for SQL composition. Not mapping. So, not supported any time
soon I guess.

On Thu, Sep 12, 2013 at 3:36 AM, liujunjie [email protected] wrote:

like:

Not support now ?

—
Reply to this email directly or view it on GitHubhttps://github.com/mybatis/mybatis-3/issues/81
.

Frank D. Martínez M.

This would be a really useful feature!

It doesn't have to be called <include> if you are worried that people would confuse it with SQL include.

Example assuming ClassB extends ClassA:

<resultMap id="classA" class="my.package.ClassA">
  <id property="field1" column="FIELD_1" />
  <result property="field2" column="FIELD_2" />
</resultMap>
<select id="selectClassA" resultMap="classA">
  select
    A.FIELD_1,
    A.FIELD_2
  from TABLE_A A
</select>
<resultMap id="classB" class="my.package.ClassB">
  <include ref="classA" />
  <result property="field3" column="FIELD_3" />
  <result property="field4" column="FIELD_4" />
</resultMap>
<select id="selectClassB" resultMap="classB">
  select
    A.FIELD_1,
    A.FIELD_2,
    B.FIELD_3,
    B.FIELD_4
  from TABLE_A A
  inner join TABLE_B B
  on
    B.FIELD_1 = A.FIELD_1
</select>

(obviously this becomes more useful when the classA resultmap is a lot larger)

Any updates on this issue? I'm also looking for such a solution.

Unfortunately not, but MyBatis does have an "extends" attribute for resultmaps, e.g.

<resultMap id="classB" class="my.package.ClassB" extends="classA">
  <result property="field3" column="FIELD_3" />
  <result property="field4" column="FIELD_4" />
</resultMap>

An include option would be better, because extends is limited to one resultmap.

Thanks @Condor70 , "extends" is useful for me. It would be better to have "include" :+1:

Hi @ytfei ,
Could you show us how your java classes and resultMaps would look like if you can use <include /> in a resultMap?
I thought extends attribute and <association /> element is sufficient for everyone's needs.

extends only extends a single resultmap and <assosication /> assumes there is a nested class.

Here is a rather lengthy example of when <include /> could be useful:

public interface InterfaceA {
    public int getProperty1();
    public void setProperty1(int value);
}
public interface InterfaceB {
    public int getProperty2();
    public void setProperty2(int value);
}
public class ClassA implements InterfaceA {
    private final int id;
    private int property1;
    public ClassA(final int id) {
        super();
        this.id = id;
    }
    public int getId() {
        return this.id;
    }
    @Override
    public int getProperty1() {
        return this.property1;
    }
    @Override
    public void setProperty1(final int property1) {
        this.property1 = property1;
    }
}
public class ClassAB implements InterfaceA, InterfaceB {
    private final int id;
    private int property1;
    private int property2;
    public ClassAB(final int id) {
        super();
        this.id = id;
    }
    public int getId() {
        return this.id;
    }
    @Override
    public int getProperty1() {
        return this.property1;
    }
    @Override
    public void setProperty1(final int property1) {
        this.property1 = property1;
    }
    @Override
    public int getProperty2() {
        return this.property2;
    }
    @Override
    public void setProperty2(final int property2) {
        this.property2 = property2;
    }
}

with

<resultMap id="InterfaceA" class="my.package.InterfaceA">
  <result property="property1" column="PROPERTY_1" />
</resultMap>
<resultMap id="InterfaceB" class="my.package.InterfaceB">
  <result property="property2" column="PROPERTY_2" />
</resultMap>
<resultMap id="ClassA" class="my.package.ClassA">
  <constructor>
    <idArg column="ID" />
  </constructor>
  <include ref="InterfaceA" />
</resultMap>
<select id="selectClassA" resultMap="ClassA">
  select
    A.ID,
    A.PROPERTY_1
  from TABLE_A A
</select>
<resultMap id="ClassAB" class="my.package.ClassAB">
  <constructor>
    <idArg column="ID" />
  </constructor>
  <include ref="InterfaceA" />
  <include ref="InterfaceB" />
</resultMap>
<select id="selectClassAB" resultMap="ClassAB">
  select
    AB.ID,
    AB.PROPERTY_1,
    AB.PROPERTY_2
  from TABLE_AB AB
</select>

Another option would be if extends supported multiple resultmaps. Then this would be written as:

<resultMap id="InterfaceA" class="my.package.InterfaceA">
  <result property="property1" column="PROPERTY_1" />
</resultMap>
<resultMap id="InterfaceB" class="my.package.InterfaceB">
  <result property="property2" column="PROPERTY_2" />
</resultMap>
<resultMap id="ClassA" class="my.package.ClassA" extends="InterfaceA">
  <constructor>
    <idArg column="ID" />
  </constructor>
</resultMap>
<select id="selectClassA" resultMap="ClassA">
  select
    A.ID,
    A.PROPERTY_1
  from TABLE_A A
</select>
<resultMap id="ClassAB" class="my.package.ClassAB" extends="InterfaceA,InterfaceB">
  <constructor>
    <idArg column="ID" />
  </constructor>
</resultMap>
<select id="selectClassAB" resultMap="ClassAB">
  select
    AB.ID,
    AB.PROPERTY_1,
    AB.PROPERTY_2
  from TABLE_AB AB
</select>

Thanks @Condor70 for the example!
Considering the current resultMap complexity (autoMapping, columnPrefix, etc.), I am a little bit anxious about adding <include /> or multiple inheritance just to reduce a little redundancy of such a rare setup, but it's just my personal opinion.

To all,
If you think you need <include /> for your resultMap, there is a good chance that existing features can help.
You should post a question on the mailing list with concrete java/mapper code.

Regards,
Iwao

Was this page helpful?
0 / 5 - 0 ratings