mybatis中的多表查询

首先我们先创建两个表和pojo用来演示多表查询,如下:
用户表:t_emp表,其中emp_id为自增主键。
mybatis中的多表查询_第1张图片
t_emp对应的pojo:Employee

public class Employee {
    private Integer empId;

    private String empName;

    private  Integer age;

    private String gender;

    private Dept dept;

    public Employee(Integer empId, String empName, Integer age, String gender, Dept dept) {
        this.empId = empId;
        this.empName = empName;
        this.age = age;
        this.gender = gender;
        this.dept = dept;
    }
    public Employee() {
    }

   //Setter and Getter方法必须要有,这里不在展示
    
    @Override
    public String toString() {
        return "Employee{" +
                "empId=" + empId +
                ", empName='" + empName + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                ", dept=" + dept +
                '}';
    }
}

部门表:t_dept,dept_id为主键

mybatis中的多表查询_第2张图片
对应的pojo:Dept

public class Dept {
    private Integer deptId;

    private String deptName;

    private Collection<Employee> employees;

    public Dept(Integer deptId, String deptName) {
        this.deptId = deptId;
        this.deptName = deptName;
    }

    public Dept() {
    }

     //Setter and Getter方法必须要有,这里不在展示
     
    @Override
    public String toString() {
        return "Dept{" +
                "deptId=" + deptId +
                ", deptName='" + deptName + '\'' +
                ", employees=" + employees +
                '}';
    }
}

在核心配置文件中的Setting的配置

<settings>
        
        <setting name="mapUnderscoreToCamelCase" value="true"/>
settings>

IDEA中的目录
mybatis中的多表查询_第3张图片

多对一查询

多对一查询:第一张表中的多条记录可能对应第二张表中的一条记录,并且在第一张表对应的类中存在第二张表对应类的实例变量。对应到例子中,员工表中,不同的员工肯属于同一个部门,员工表中有部门类型的实例。这里提供三种查询方式。

使用级联处理映射关系

EmployeeMapper.xml中:


   <resultMap id="empAndDeptResultMapOne" type="pojo.Employee">
        <id column="emp_id" property="empId"/>
        <result column="emp_name" property="empName"/>
        <result column="age" property="age"/>
        <result column="gender" property="gender"/>
        <result column="dept_id" property="dept.deptId"/>
        <result column="dept_name" property="dept.deptName"/>
   resultMap>

使用asscoiation处理映射关系

EmployeeMapper.xml中:

 <resultMap id="empAndDeptResultMapTwo" type="pojo.Employee">
        <id column="emp_id" property="empId"/>
        <result column="emp_name" property="empName">/result>
        <result column="age" property="age"/>
        <result column="gender" property="gender"/>
        
        <association property="dept" javaType="pojo.Dept">
            <id column="dept_id" property="deptId"/>
            <result column="dept_name" property="deptName"/>
        association>
resultMap>

使用分步查询处理映射关系

DeptMapper中:


<select id="getDeptById" resultType="pojo.Dept">
        select *from t_dept where dept_id = #{dept_id};
select>

EmployeeMapper.xml中:

<resultMap id="empAndDeptResultMapByStep" type="pojo.Employee">
        <id column="emp_id" property="empId"/>
        <result column="emp_name" property="empName"/>
        <result column="age" property="age"/>
        <result column="gender" property="gender"/>

        
        <association property="dept"
                     select="mapper.DeptMapper.getDeptById"
                     column="dept_id"/>
resultMap>

 <select id="getDeptById" resultType="pojo.Dept">
        select *from t_dept where dept_id = #{deptId};
select>

一对多查询

一对多查询:第一张表中的一条记录对应第二张表中的多条记录,并且在第一张表对应类中有第二张表对应类中的实例集合属性。对应到例子当,一个部门可能会有多个员工,相应的部门表对应类中有List集合类型的属性。这里提供两种查询方式。

使用collection处理映射关系

DeptMapper中:

<resultMap id="deptAndEmpResultMap" type="pojo.Dept">
        <id column="dept_id" property="deptId"/>
        <result column="dept_name" property="deptName"/>
        
        <collection property="employees" ofType="pojo.Employee">
            <id column="emp_id" property="empId"/>
            <result column="emp_name" property="empName"/>
            <result column="age" property="age"/>
            <result column="gender" property="gender"/>
        collection>
  resultMap>

使用分步查询处理映射关系

EmployeeMapper.xml中:

<select id="getEmpByDept" resultType="pojo.Employee">
        select *from t_emp where dept_id = #{dept_id};
select>

DeptMapper中:

<resultMap id="deptAndEmpByStepResultMap" type="pojo.Dept">
        <id column="dept_id" property="deptId"/>
        <result column="dept_name" property="deptName"/>
        <collection property="employees" ofType="Employee" select="mapper.EmpMapper.getEmpByDept" column="dept_id"/>
 resultMap>
 
 <select id="getEmpByDept" resultType="pojo.Employee">
     select *from t_emp where dept_id = #{dept_id};
 select>

分步查询的延迟加载和按需加载

在mybatis的核心配置文件当中可以配置这两种属性。

<settings>
        
        <setting name="lazyLoadingEnabled" value="false"/>
        
        <setting name="aggressiveLazyLoading" value="false"/>
settings>

按需加载:按需加载又称懒加载,在需要时才会去加载。我们以多对一的分步查询为例。

@Test
    public void testGetAllEmpAndDeptByStep(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
        List<Employee> employeeList = empMapper.getAllEmpAndDeptByStep();
        employeeList.forEach((Employee employee) ->{
            System.out.println(employee.getEmpName());
        });
    }

我们在设置属性lazyLoadingEnabled之前:
编译后的日志记录如下:
mybatis中的多表查询_第4张图片
尽管我们只需要emp_name,仅通过select * from t_emp就可以将所需数据查出来,但是我们还是进行了两步查询。

我们将属性lazyLoadingEnabled设置为true,aggressiveLazyLoading默认为false,所以此时是按需加载。

编译后的日志记录如下:
mybatis中的多表查询_第5张图片
因为需要的对象仅通过select * from t_emp就能得出,所以只会进行这一次查询。

此时我们再将属性aggressiveLazyLoading设置为true,编译后的日志记录如下:
mybatis中的多表查询_第6张图片
此时不在是按需加载,而是完整加载。

在按需加载时,我们可以在collection标签或者是association标签中设置的fetchType属性设置当前的分步查询是否使用延迟加载, fetchType="lazy(延迟加载)|eager(立即加载)

你可能感兴趣的:(mybatis,java,intellij-idea)