Delayed loading of Mybatis

Delayed loading

Delayed loading is applied in combination with associated query. That is, it only works on the < Association > and < Collection > tags

For the associated query, if the delayed loading strategy is not adopted, but the associated slave information is queried at one time, the N+1 problem will occur when there is more primary information, resulting in reduced performance. For example, the relationship between user information and order information is one to many. When querying user information, the association query order information is set. If the delayed loading strategy is not adopted, assuming a total of 100 users, we only need one SQL query to query the basic information of these 100 users

select * from user;

If the associated query is enabled and the loading is not delayed, 100 SQL messages will be sent to check the order information corresponding to the 100 users, which will cause unnecessary performance overhead (in fact, I think it is more appropriate to call it 1+N problem)

select * from orders where u_id = 1;
select * from orders where u_id = 2;
....
select * from orders where u_id = 100;

When we may only care about the order information of the user with id=3, a lot of related information is useless. Therefore, using the delayed loading strategy, we can load the slave information on demand. When we need the slave information corresponding to a master information, we can send SQL to execute the query instead of finding it all at once, which can improve the performance very well.

In addition, for the N+1 problem, in addition to the delayed loading strategy, the association query is carried out on demand. In some scenarios, it is really necessary to query all the slave information associated with the master information. In the above example, what if you really need to query all the order information associated with these 100 users? Here are two solutions.

1. Connection query is adopted, and only one SQL is used, as shown below

select * from user as u left join orders as o on u.id = o.u_id;

However, the result of using join query is the Cartesian product of two tables, and the data needs to be grouped by ourselves

2. It is completed IN two steps. First, execute an SQL to find out all user information, and put the user's id IN a set, and then the second SQL can be queried by using the IN keyword. This method can also be simplified to sub query, as follows

select * from orders where u_id in (select id from user);

Now, the delayed loading of mybatis is turned off by default. It can be turned on through < setting name = "lazyloading enabled" value = "true" / > in the global configuration file. After it is turned on, all SELECT queries will adopt the delayed loading strategy if they have associated objects. Of course, you can also disable the delayed loading policy for a specified CRUD tag separately. By setting fetchType=eager in the SELECT tag, you can turn off the delayed loading of the tag.

(there is also a concept of intrusive delayed loading. In the configuration file, < setting name = "aggressivelazyloading" value = "true" >To enable, that is to say, when accessing the master information in the master object, it will trigger the delayed loading, which will be queried from the information. In fact, this is not the real delayed loading. The real delayed loading should trigger the delayed loading when accessing the slave information in the master object to load the slave information. Intrusive delayed loading is turned off by default, Generally, you can leave him alone)

Note that deferred loading makes sense only in the context of associated queries. It needs to be used in conjunction with the < Association > and < Collection > tags under the < resultmap > tag

<!-- StudentMapper.xml -->
<resultMap id="studentExt" type="com.yogurt.po.StudentExt">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="score" column="score"/>
        <result property="age" column="age"/>
        <result property="gender" column="gender"/>
		<!-- When the delayed loading master switch is on, resultMap Lower association and collection Label, if passed select Property specifies the of the nested query SQL,Then its fetchType Default is lazy , when the master switch of delayed loading is on, it is necessary to disable delayed loading for individual associated queries fetchType = eager -->
    	<!--
 		column Used to specify the columns to use for the associated query
		property Used to specify to encapsulate into StudentExt Which attribute in
		javaType The object used to get the association of the specified query
		select When used to specify Association query,Which one is called DQL
		-->
        <association property="clazz" javaType="com.yogurt.po.Clazz" column="class_id"
                     select="com.yogurt.mapper.ClassMapper.findById" fetchType="lazy"/>

    </resultMap>

Keywords: Mybatis

Added by designxperts on Tue, 08 Feb 2022 06:03:00 +0200