mybatis学习笔记(7):一对多关联查询

一对多或多对多对于后面的多方使用<collection>标签封装关联数据
准备工作
创建两个表:
tbl_employee:员工表,使用dept_id和部门表的id关联
这里写图片描述
tbl_department:部门表
这里写图片描述

创建两个实体类:
Employee.java:

public class Employee {

    private Integer id;
    private String lastName;
    private String gender;
    private String email;

    public Employee() {
        super();
    }
    public Employee(Integer id, String lastName, String gender, String email) {
        super();
        this.id = id;
        this.lastName = lastName;
        this.gender = gender;
        this.email = email;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    @Override
    public String toString() {
        return "Employee [id=" + id + ", lastName=" + lastName + ", gender="
                + gender + ", email=" + email + "]";
    }
}

Department.java

public class Department {

    private Integer id;
    private String departmentName;
    private List<Employee> emps;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getDepartmentName() {
        return departmentName;
    }
    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }
    public List<Employee> getEmps() {
        return emps;
    }
    public void setEmps(List<Employee> emps) {
        this.emps = emps;
    }
    @Override
    public String toString() {
        return "Department [id=" + id + ", departmentName=" + departmentName
                + "]";
    }
}

在一方创建多方的集合属性来封装多方数据

1. 关联查询方式

1.1 创建Mapper文件
首先定义一个接口:

public interface DepartmentMapper {

    public Department getDeptByIdPlus(Integer id);

}

配置Mapper XML文件:

<?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">
<!-- namespace命名空间,唯一标识。一般指定为自定义的接口文件,下面相当于这个接口的实现类 -->
<mapper namespace="com.mybatis.mapper.DepartmentMapper">
    <!-- 定义结果集,column表示sql查询列,property表示映射到实体的属性 -->
    <resultMap type="com.mybatis.domain.Department" id="myDept">
        <id column="id" property="id"/>
        <result column="department_name" property="departmentName"/>
        <!-- 关联集合对象,注意这里配置的是ofType -->
        <collection property="emps" ofType="com.mybatis.domain.Employee">
            <!-- 员工信息主键-->
            <id column="e_id" property="id"/>
            <result column="last_name" property="lastName"/>
            <result column="email" property="email"/>
            <result column="gender" property="gender"/>
        </collection>
    </resultMap>

    <select id="getDeptByIdPlus" resultMap="myDept">
        SELECT d.id,d.department_name,
            e.id e_id,e.last_name,e.email,e.gender
        FROM tbl_department d
        LEFT JOIN tbl_employee e
         ON d.id = e.dept_id
        WHERE d.id = #{id}
    </select>

</mapper>

注:column是查询列,property是映射的实体类属性。还有注意配置项ofType和之前一对一关联查询的不同

1.2 注册Mapper 文件
在conf配置文件中注册:

<mappers>
    <!-- 直接使用接口文件,必须将xml映射文件放在相同的文件夹下,会自动匹配置文件 -->
     <mapper class="com.mybatis.mapper.DepartmentMapper"/>
</mappers>

1.3 测试

@Test
public void getDeptByIdPlus(){
    SqlSessionFactory factory = MyBatisUtil.getFactory();
    SqlSession session = factory.openSession();
    DepartmentMapper mapper = session.getMapper(DepartmentMapper.class);
    Department dept = mapper.getDeptByIdPlus(1);
    System.out.println(dept);
    System.out.println(dept.getEmps());
    session.commit();
    session.close();
}

1.4 结果
这里写图片描述

2. 分步查询

2.1 创建员工的Mapper文件
接口:

public interface EmployeeMapper {
    //通过deptId查询员工信息
    public Employee getEmpByDeptId(Integer deptId);

}

Mapper XML文件:

<?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">
<!-- namespace命名空间,唯一标识。一般指定为自定义的接口文件,下面相当于这个接口的实现类 -->
<mapper namespace="com.mybatis.mapper.EmployeeMapper">
    <select id="getEmpByDeptId" resultType="com.mybatis.domain.Employee">
        select * from tbl_employee
        where dept_id = #{deptId}
    </select>
</mapper>

2.2 配置部门的Mapper文件
接口文件:

public interface DepartmentMapper {
    //分步查询
    public Department getDeptBystep(Integer id);
}

Mapper XML文件:

<?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">
<!-- namespace命名空间,唯一标识。一般指定为自定义的接口文件,下面相当于这个接口的实现类 -->
<mapper namespace="com.mybatis.mapper.DepartmentMapper">
    <resultMap type="com.mybatis.domain.Department" id="myDeptBystep">
        <id column="id" property="id"/>
        <result column="department_name" property="departmentName"/>
        <!-- 将第一步查询的部门id传给EmployeeMapper的getEmpByDeptId方法进行第二部查询 -->
        <collection property="emps"
         select="com.mybatis.mapper.EmployeeMapper.getEmpByDeptId"
         column="id">
        </collection>
    </resultMap>
    <!-- 第一步查询 -->
    <select id="getDeptBystep" resultMap="myDeptBystep">
        SELECT id,department_name
        FROM tbl_department
        WHERE id = #{id}
    </select>
</mapper>

2.3 将上面定义的两个Mapper文件注册

<mappers>
    <!-- 直接使用接口文件,必须将xml映射文件放在相同的文件夹下,会自动匹配置文件 -->
     <mapper class="com.mybatis.mapper.EmployeeMapper"/>
     <mapper class="com.mybatis.mapper.DepartmentMapper"/>
</mappers>

2.4 测试

@Test
public void getDeptBystep(){
    SqlSessionFactory factory = MyBatisUtil.getFactory();
    SqlSession session = factory.openSession();
    DepartmentMapper mapper = session.getMapper(DepartmentMapper.class);
    Department dept = mapper.getDeptBystep(1);
    System.out.println(dept);
    System.out.println(dept.getEmps());
    session.commit();
    session.close();
}

2.5 结果

这里写图片描述
可以看到发出了两条sql
也支持懒加载模式

注:<collection> 标签里面的column可以使用键值对传多列值,例如:

<collection property="emps"
         select="com.mybatis.mapper.EmployeeMapper.getEmpByDeptId"
         column="{deptId=id,xx=xx}">
        </collection>

对于 column=”{deptId=id,xx=xx}” 中deptId表示getEmpByDeptId方法的参数,id是第一步查询的id列。

<collection> 标签还包含一个fetchType属性,这个可以设置抓取方式,即是懒加载还是立即加载。

猜你喜欢

转载自blog.csdn.net/abc997995674/article/details/80875048