Lazy loading is a performance optimization technique used in MyBatis for handling one-to-many or many-to-many relationships during database queries.
Consider a scenario with employee and department tables. A typical LEFT JOIN operation would fetch all related data in a single query. However, when department information is rarely accessed, lazy loading allows us to defer the retrieval of department data until it's actually needed, improving initial query performance.
Enabling Lazy Loading
Configuration Settings
Two key configuration properties control loading behavior:
lazyLoadingEnabled: Set to true to enable lazy loading. This is mutually exclusive with aggressive loading.aggressiveLoadingEnabled: Set to true to enable eager loading of all associated objects. This conflicts with lazy loading.
To enable lazy loading globally, configure these settigns in your mybatis.xml file:
<configuration>
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLoadingEnabled" value="false"/>
</settings>
</configuration>
Query Implementation
Prerequisites
Assume we have two entity classes representing employees and departments:
public class Department {
private Integer deptid;
private String dname;
}
public class Employee {
private Integer id;
private String name;
private Integer age;
private Department department;
}
XML Mapping Configuration
Instead of using a direct LEFT JOIN, we split the query into separate operations to maintain control over when associated data is loaded.
First, define the individual queries:
<select id="findDepartmentById">
SELECT * FROM t_dept WHERE deptid = #{deptid}
</select>
<select id="findAllEmployees" resultMap="employeeMap">
SELECT * FROM t_emp
</select>
Next, configure the result mapping with association:
<resultMap id="employeeMap" type="Employee">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<association property="department" javaType="Department"
column="deptId" select="findDepartmentById">
<id column="deptid" property="deptid"/>
<result column="dname" property="dname"/>
</association>
</resultMap>
Complete Example
<resultMap id="employeeMap" type="Employee">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<association property="department" javaType="Department"
column="deptId" select="findDepartmentById">
<id column="deptid" property="deptid"/>
<result column="dname" property="dname"/>
</association>
</resultMap>
<select id="findDepartmentById">
SELECT * FROM t_dept WHERE deptid = #{deptid}
</select>
<select id="findAllEmployees" resultMap="employeeMap">
SELECT * FROM t_emp
</select>