How to map a myBatis result to multiple objects?

2019-05-18 19:30发布

Is it possible in myBatis 3 to map a single result to multiple objects, ensuring that the objects all reference the same instance? Is there an example of this I could reference?

Updated to add more detail:

For instance, let's say I store information regarding Contacts for my application in my DB. I want to know if it's possible to use myBatis to map the same instance of a contact to, say, a Listing class, which holds a Contact:

public class Listing {
    private Contact myContact;
    //getters & setters...
}

as well as to a ContactsHolder class, which also holds a Contact:

public class ContactsHolder {
    private Contact aContact
    //getters & setters...
}

I need the object that is mapped by myBatis to both the Listing and ContactsHolder classes to be the same instance. Is this possible?

2条回答
Juvenile、少年°
2楼-- · 2019-05-18 19:58

This can be done with standard result mapping if you use select to fetch the associated contact and both objects are fetched in the same session.

Modify result maps for Listing and ContactsHolder:

<resultMap type="Listing" id="listingMap">
   <association property="myContact" column="contact_id" javaType="Contact" select="selectContact"/>
</resultMap>

<resultMap type="ContactsHolder" id="contactsHolderMap">
   <association property="aContact" column="contact_id" javaType="Contact" select="selectContact"/>
</resultMap>

Now create a query selectContact:

<select id='selectContact' resultType='Contact'>
     SELECT * from contact where id = #{id}
</select>

Now if you create some select that uses both listingMap and contactsHolderMap to map Listing and ContactsHolder records that reference the same contact they will both query for the contact using the same id.

Mybatis uses local cache for all objects read in a session so during fetching of the second associated contact the cache will be hit and the same object will be reused.

Even if you do two queries manually to get Listing and ContactsHolder in the same transaction the same Contact will be used in both returned objects.

查看更多
Juvenile、少年°
3楼-- · 2019-05-18 20:10

No, MyBatis isn't able to do that with standard result mapping. (at least to my knowledge). You could select the "Contact" object, then build a Listing and ContactsHolder manually with both of them referencing the Contact.

Or implement a custom ResultSetHandler.

It's kind of a peculiar request, I'm not sure why you want the same instances shared across two objects like that. That's probably why no feature like this exists in MyBatis 3.

查看更多
登录 后发表回答