The principle of encapsulation object of nested result query in mybatis one-to-many relationship

Mybatis mainly loads association objects in mapping files in two ways: nested queries and nested results.

Nested query refers to executing another SQL mapping statement to return the expected complex type;
nested results are a subset of the repeated joint results that are processed using nested result mapping.

 This article explains the principle of nested result query one-to-many encapsulated objects.

First, the result set obtained through SQL query is as follows:

 It is not difficult to find that there are multiple resources with ID 7, and multiple roles can access this resource.

In the mapper.xml file:

 This is the encapsulation rule for a one-to-many relationship

 

<!--1.嵌套结果-->
<select id="selectUser" resultMap="selectUser1">
        select u.id,u.name,u.age,o.id as order_id,o.name as order_name from t_p_user u left join t_p_user_order o
        on u.id = o.user_id and u.id = #{id}
    </select>

    <resultMap id="selectUser1" type="com.seakoon.model.User">
        <id column="id" property="id" />
        <result column="name" property="name"/>
        <result column="age" property="age"/>
        <collection property="orders" ofType="com.seakoon.model.UserOrder" column="id">
            <id column="order_id" property="id" />
            <result column="order_name" property="name" />
            <result column="id" property="userId" />
        </collection>
    </resultMap>

So why are there obviously multiple records in the database, and why is there only one object after encapsulating it into an object? Instead of multiple objects, what about each object having one role in "many"?

It is not difficult to find that there is an id tag in each resultMap, including the collection tag (association tag) in the one-to-many (one-to-one) resultMap. The id tag must also be written in the collection tag (association tag). The principle is here!

MyBatis will encapsulate them uniformly based on ID. In the above example, there are several records with ID 7, then MyBatis will treat it as an object, and then the role information in each record with ID 7 will be encapsulated into the roles collection. The role information recorded with ID 8 will not be encapsulated into the roles collection of object ID 7.

In short, objects with the same ID but different rids are encapsulated into an object. Different rids correspond to different roles, and then they are encapsulated into the roles collection of this entity class.

It is not difficult to infer that if there is another one-to-many relationship field List<Other> others in the role entity class, write the resultMap according to this rule as follows:

Then it will encapsulate the same rid but different oid into a role object, and then encapsulate different other information into the others collection in this object.

 

2.1.5.1 Basis for merging
When mybatis processes the results, it will determine whether the objects are the same. If they are the same, the results will be merged with the previous results.

So, how to judge whether the results are the same?

The first is to compare by id. If the id is not configured, each field is compared (at this time, as long as there is a different object with a different field).

2.1.5.2 The role of id
In the generated XML, if we have a primary key, a corresponding id attribute will generally be generated.

The id attribute can be used to determine whether the obtained data belongs to the same object.

In the above example, there are three id=1 found in the database, then mybatis can know that these three pieces of data correspond to the same object when processing the results, so as to merge them.
2.2 Collection nested query method

 Use nested query: Use a new sql to query order data. The parameter is the value of the column attribute. If there are multiple parameters: use
column="{property1 = column1,property2 = column2...}"

Writing method in mapper.xml

<!--2.嵌套查询-->
    <select id="selectUserNew" resultMap="selectUser2">
        select id,name,age from t_p_user where id = #{id}
    </select>

    <resultMap id="selectUser2" type="com.seakoon.model.User">
        <id column="id" property="id" />
        <result column="name" property="name"/>
        <result column="age" property="age"/>
        <collection property="orders" ofType="com.seakoon.model.UserOrder" column="id" javaType="java.util.ArrayList"
        select="selectOrderById">
            <id column="order_id" property="id" />
            <result column="order_name" property="name" />
            <result column="id" property="userId" />
        </collection>
    </resultMap>

    <select id="selectOrderById" resultType="com.seakoon.model.UserOrder">
        select id,name,user_id as userId from t_p_user_order where user_id = #{id}
    </select>

In column, you need to fill in {attribute name = column name (alias)} (if there is only one parameter, you can also directly fill in the column name and pass in the parameter). If multiple parameters are passed, it is {attribute name 1 = column name 1, attribute name 2 = column name 2}.

The select attribute value is com.homejim.mybatis.mapper.PostMapper.selectPostByBlogId, and the corresponding parameterType is java.util.Map (you can also leave it blank).

The attribute value of fetchType is lazy (delayed loading, corresponding configuration is required) or eager.

Guess you like

Origin blog.csdn.net/zlfjavahome/article/details/133383505