• mybatis中的多表查询


    首先我们先创建两个表和pojo用来演示多表查询,如下:
    用户表:t_emp表,其中emp_id为自增主键。
    在这里插入图片描述
    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 +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    部门表:t_dept,dept_id为主键

    在这里插入图片描述
    对应的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 +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

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

    <settings>
            
            <setting name="mapUnderscoreToCamelCase" value="true"/>
    settings>
    
    • 1
    • 2
    • 3
    • 4

    IDEA中的目录
    在这里插入图片描述

    多对一查询

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

    使用级联处理映射关系

    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>
       
       <select id="getAllEmpAndDeptOne" resultMap="empAndDeptResultMapOne">
            SELECT t_emp.*,t_dept.dept_name FROM t_emp LEFT JOIN t_dept ON t_dept.dept_id = t_emp.dept_id;
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    使用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>
    
    <select id="getAllEmpAndDeptTwo" resultMap="empAndDeptResultMapTwo">
            SELECT t_emp.*,t_dept.dept_name FROM t_emp LEFT JOIN t_dept ON t_dept.dept_id = t_emp.dept_id;
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

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

    DeptMapper中:

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

    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="getAllEmpAndDeptByStep" resultMap="empAndDeptResultMapByStep">
            select *from t_emp;
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    一对多查询

    一对多查询:第一张表中的一条记录对应第二张表中的多条记录,并且在第一张表对应类中有第二张表对应类中的实例集合属性。对应到例子当,一个部门可能会有多个员工,相应的部门表对应类中有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>
    
      <select id="getAllDeptAndEmp" resultMap="deptAndEmpResultMap">
            SELECT *FROM t_dept LEFT JOIN  t_emp ON t_dept.dept_id = t_emp.dept_id ;
      select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

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

    EmployeeMapper.xml中:

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

    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="getAllDeptAndEmpByStep" resultMap="deptAndEmpByStepResultMap">
            SELECT *FROM t_dept ;
     select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

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

    <settings>
            
            <setting name="lazyLoadingEnabled" value="false"/>
            
            <setting name="aggressiveLazyLoading" value="false"/>
    settings>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

    @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());
            });
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

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

    编译后的日志记录如下:
    在这里插入图片描述
    因为需要的对象仅通过select * from t_emp就能得出,所以只会进行这一次查询。

    此时我们再将属性aggressiveLazyLoading设置为true,编译后的日志记录如下:
    在这里插入图片描述
    此时不在是按需加载,而是完整加载。

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

  • 相关阅读:
    JPA联合主键
    [HDLBits] Count clock
    HTML5期末大作业——HTML+CSS+JavaScript平遥古城旅游景点介绍(6页)
    Java 对象是什么样子的?
    python中的闭包函数&装饰器
    外包干了3天,技术退步明显.......
    计算机竞赛 基于深度学习的人脸识别系统
    【Spring 事务和事务传播机制】
    MVVM模式根模块
    db2数据仓库集群的搭建
  • 原文地址:https://blog.csdn.net/m0_62969222/article/details/126003498