[Mybatis from entry to actual combat tutorial] Chapter 6 Detailed Explanation of Mybatis Lazy Loading

6. Mybatis lazy loading

6.1 What is lazy loading

    When you need to query related information, using the MyBatis lazy loading feature can effectively reduce the pressure on the database. For the first query, only the main information is queried, and the related information is loaded when the user obtains it.
    
    Lazy loading is used for cascading. The purpose of lazy loading is to reduce the waste of memory and reduce the burden on the system. You can understand it as on-demand loading. When I call the associated data, I only interact with the database, otherwise I don’t interact.
    
    resultMap can implement advanced mapping (using association and collection to realize one-to-one and one-to-many mapping), and association and collection have lazy loading function.

6.2 Turn on the delay loading switch

    Configure in the MyBatis core configuration file: lazyLoadingEnabled, aggressiveLazyLoading.

setting items describe allowance Defaults
lazyLoadingEnabled Globally set lazy loading. If set to 'false', all associated true, false false
aggressiveLazyLoading When set to 'true', lazy loaded objects may be fully loaded with any lazy properties. Otherwise, each attribute is loaded on demand true, false true
<!-- 全局参数设置 -->
<settings>
    <!-- 开启延迟加载 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>

6.3 Entity class

6.3.1 Department class

public class Dept {

    private Integer deptno;
    private String dname;
    private String loc;
    /**
     * 关系属性
     */
    private List<Emp> empList;

    public Integer getDeptno() {
        return deptno;
    }

    public void setDeptno(Integer deptno) {
        this.deptno = deptno;
    }

    public String getDname() {
        return dname;
    }

    public void setDname(String dname) {
        this.dname = dname;
    }

    public String getLoc() {
        return loc;
    }

    public void setLoc(String loc) {
        this.loc = loc;
    }

    public List<Emp> getEmpList() {
        return empList;
    }

    public void setEmpList(List<Emp> empList) {
        this.empList = empList;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "deptno=" + deptno +
                ", dname='" + dname + '\'' +
                ", loc='" + loc + '\'' +
                '}';
    }
}

6.3.2 Employee class

public class Emp {

    private Integer empno;
    private String ename;
    private String job;
    private Integer mgr;
    private Date hiredate;
    private Double sal;
    private Double comm;
    private Integer deptno;
    /**
     * 关系属性
     */
    private Dept dept;

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public Integer getMgr() {
        return mgr;
    }

    public void setMgr(Integer mgr) {
        this.mgr = mgr;
    }

    public Date getHiredate() {
        return hiredate;
    }

    public void setHiredate(Date hiredate) {
        this.hiredate = hiredate;
    }

    public Double getSal() {
        return sal;
    }

    public void setSal(Double sal) {
        this.sal = sal;
    }

    public Double getComm() {
        return comm;
    }

    public void setComm(Double comm) {
        this.comm = comm;
    }

    public Integer getDeptno() {
        return deptno;
    }

    public void setDeptno(Integer deptno) {
        this.deptno = deptno;
    }

    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "empno=" + empno +
                ", ename='" + ename + '\'' +
                ", job='" + job + '\'' +
                ", mgr=" + mgr +
                ", hiredate=" + hiredate +
                ", sal=" + sal +
                ", comm=" + comm +
                ", deptno=" + deptno +
                '}';
    }
}

6.4 Use association to implement lazy loading

    Query employee and associated department information.

6.4.1 mapper interface

public interface EmpMapper {

    /*
     * 查询所有员工的信息,并关联查询部门信息
     */
    List<Emp> select();
}

public interface DeptMapper {

    /*
     * 根据部门编号查询部门信息
     */
    Dept selectById(Integer deptno);
}

6.4.2 mapper file

    The premise of lazy loading is that Sql needs to be separated, and associated query Sql is no longer used.
    
    For example, we want to query the information of all employees, and query department information in association; if we want to implement lazy loading of department information, then querying employee information is an independent Sql, and querying department information according to the department number is also an independent Sql. When querying employee information At this time, if the department information is needed, then call the Sql to query the department information according to the department number.

Query department information according to department number:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.newcapec.mapper.DeptMapper">

    <select id="selectById" parameterType="java.lang.Integer" resultType="com.newcapec.entity.Dept">
        select deptno,dname,loc from dept where deptno=#{deptno}
    </select>
</mapper>

Query employee information (single table query), and associate department information through the above query:

    Attributes of the association tag:
        select: The statementId corresponding to the sql of the associated data query when performing lazy loading.
            The executed associated query statement is in the same mapper file: just fill in the statementId directly; the
            executed associated query statement is in a different mapper file: namespace.statementId;
        column: the field name associated with it when executing the relational table information query.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.newcapec.mapper.EmpMapper">

    <resultMap id="baseResultMap" type="com.newcapec.entity.Emp">
        <id column="empno" property="empno"/>
        <result column="ename" property="ename"/>
        <result column="job" property="job"/>
        <result column="mgr" property="mgr"/>
        <result column="hiredate" property="hiredate"/>
        <result column="sal" property="sal"/>
        <result column="comm" property="comm"/>
        <result column="deptno" property="deptno"/>
        <association property="dept" javaType="com.newcapec.entity.Dept"
                     select="com.newcapec.mapper.DeptMapper.selectById" column="deptno">
        </association>
    </resultMap>
    <select id="select" resultMap="baseResultMap">
        select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
    </select>
</mapper>

6.4.3 Testing

public class LazyLoadingTest {

    @Test
    public void testOneToOne() {
        SqlSession sqlSession = MybatisUtil.getSession();
        EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);

        List<Emp> list = empMapper.select();
        for (Emp emp : list) {
            System.out.println(emp.getEmpno() + "--" + emp.getEname() + "--" + emp.getJob());
            System.out.println("----------");
            // 需要使用关联信息
            Dept dept = emp.getDept();
            if (dept != null) {
                System.out.println(dept.getDeptno() + "--" + dept.getDname() + "--" + dept.getLoc());
            }
            System.out.println("-----------------分割线----------------");
        }

        sqlSession.close();
    }
}

6.5 Use collection to implement lazy loading

6.5.1 mapper interface

public interface DeptMapper {
    
    /*
     * 查询所有部门信息,并关联部门对应的员工信息
     */
    List<Dept> select();
}

public interface EmpMapper {

    /*
     * 根据部门编号查询对应的员工信息
     */
    List<Emp> selectByDeptno(Integer deptno);
}

6.5.2 mapper file

Query employee information based on department number:

<select id="selectByDeptno" parameterType="java.lang.Integer" resultType="com.newcapec.entity.Emp">
    select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp where deptno=#{deptno}
</select>

Query department information (single-table query), and associate employee information in the department through the above query:

<resultMap id="baseResultMap" type="com.newcapec.entity.Dept">
    <id column="deptno" property="deptno"/>
    <result column="dname" property="dname"/>
    <result column="loc" property="loc"/>
    <!--关联信息描述-->
    <collection property="empList" ofType="com.newcapec.entity.Emp"
                select="com.newcapec.mapper.EmpMapper.selectByDeptno" column="deptno">
    </collection>
</resultMap>
<select id="select" resultMap="baseResultMap">
    select deptno,dname,loc from dept
</select>

6.5.3 Testing

@Test
public void testOneToMany() {
    SqlSession sqlSession = MybatisUtil.getSession();

    DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
    List<Dept> list = deptMapper.select();
    for (Dept dept : list) {
        System.out.println(dept.getDeptno() + "--" + dept.getDname() + "--" + dept.getLoc());

        //查询关联信息
        List<Emp> empList = dept.getEmpList();
        for (Emp emp : empList) {
            System.out.println("员工姓名:" + emp.getEname());
        }
    }
    sqlSession.close();
}

Guess you like

Origin blog.csdn.net/ligonglanyuan/article/details/124397287