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

在mybatis中,对于一对一、多对一都可以使用<association>标签关联一方。
准备工作,创建两个表:
tbl_employee:员工表,使用dept_id关联部门表
这里写图片描述

tbl_department:
这里写图片描述

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

public class Employee {

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

    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;
    }
    public Department getDept() {
        return dept;
    }
    public void setDept(Department dept) {
        this.dept = dept;
    }
    @Override
    public String toString() {
        return "Employee [id=" + id + ", lastName=" + lastName + ", gender="
                + gender + ", email=" + email + ", dept=" + dept + "]";
    }
}

Department.java:

public class Department {

    private Integer id;
    private String departmentName;

    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;
    }
    @Override
    public String toString() {
        return "Department [id=" + id + ", departmentName=" + departmentName
                + "]";
    }
}

1. 关联查询方式

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

public interface EmployeeMapperPlus {
    public Employee getEmpAndDeptById(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.EmployeeMapperPlus">
<!-- 定义结果集,column表示sql查询列,property表示映射到实体的属性 -->
<resultMap type="com.mybatis.domain.Employee" id="myEmp">
    <id column="id" property="id"/>
    <result column="last_name" property="lastName"/>
    <result column="gender" property="gender"/>
    <result column="email" property="email"/>
    <!-- 关联对象 -->
    <association property="dept" javaType="com.mybatis.domain.Department">
        <!-- 关联条件Employee的dept_id对应着Department的id -->
        <id column="dept_id" property="id"/>
        <result column="department_name" property="departmentName"/>
    </association>
</resultMap>
<!-- resultMap指定使用上面定义的结果集,查询使用关联查询,查询列要和上面的column对应 -->
<select id="getEmpAndDeptById" resultMap="myEmp">
    select e.id,e.last_name,e.gender,e.email,e.dept_id,d.id,d.department_name
     from tbl_employee e,tbl_department d
     where e.dept_id = d.id and e.id=#{id}
</select>

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

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

1.3 测试

@Test
public void getEmpAndDeptById(){
    SqlSessionFactory factory = MyBatisUtil.getFactory();
    SqlSession session = factory.openSession();
    EmployeeMapperPlus mapper = session.getMapper(EmployeeMapperPlus.class);
    Employee employee = mapper.getEmpAndDeptById(3);
    System.out.println(employee);
    session.commit();
    session.close();
}

1.4 结果
这里写图片描述
可以看到关联成功

需要注意的地方:
1. 上面使用tbl_employee表中的dept_id列关联 tbl_department表的id,在实体类Employee中 不需要定义dept_id属性,定义一个Department类的属性,然后通过关联查询将关联数据塞进去。
2.在 <association>标签中需要配置javaType的值,指定关联的类型。


2. 分部查询

2.1 创建部门的Mapper文件
接口:

public interface DepartmentMapper {

    public Department getDeptById(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">
    <select id="getDeptById" resultType="com.mybatis.domain.Department">
        select * from tbl_department
        where id = #{id}
    </select>

</mapper>

配置Department实体的Mapper文件,创建getDeptById方法。
并将之注册:

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

2.2 配置Employee的Mapper文件
接口:

public interface EmployeeMapperPlus {

    public Employee getEmpAndDeptByStep(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.EmployeeMapperPlus">
    <resultMap type="com.mybatis.domain.Employee" id="myEmpByStep">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <result column="email" property="email"/>
        <!-- 使用select属性指定第二步调用的方法,并通过column指定传递的参数值,这个值是第一步的查询的数据 -->
        <association property="dept" 
            select="com.mybatis.mapper.DepartmentMapper.getDeptById"
            column="dept_id">
        </association>
    </resultMap>
    <!-- 第一步值只查询tbl_employee表 -->
    <select id="getEmpAndDeptByStep" resultMap="myEmpByStep">
        select id,last_name,gender,email,dept_id
         from tbl_employee
         where id = #{id}
    </select>
</mapper>

2.3 测试

@Test
public void getEmpAndDeptByStep(){
    SqlSessionFactory factory = MyBatisUtil.getFactory();
    SqlSession session = factory.openSession();
    EmployeeMapperPlus mapper = session.getMapper(EmployeeMapperPlus.class);
    Employee employee = mapper.getEmpAndDeptByStep(3);
    System.out.println(employee);
    session.commit();
    session.close();
}

2.4 结果
这里写图片描述
可以看到发出了两个sql,是分步查询的,而不是之前那样一条语句关联查询。

2.5 配置懒加载
我们可以配置懒加载以达到在不使用关联表信息的时候不进行查询的目的
在conf文件中配置settings:

<settings>
    <!-- 设置驼峰属性 -->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
    <!-- 配置懒加载-->
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="aggressiveLazyLoading" value="false"/>
    <!-- 其他配置略 -->
</settings>

在执行测试,这次只查询员工表信息:

@Test
public void getEmpAndDeptByStep(){
    SqlSessionFactory factory = MyBatisUtil.getFactory();
    SqlSession session = factory.openSession();
    EmployeeMapperPlus mapper = session.getMapper(EmployeeMapperPlus.class);
    Employee employee = mapper.getEmpAndDeptByStep(3);
    System.out.println(employee.getLastName());
    session.commit();
    session.close();
}

结果:
这里写图片描述

可以看出,只发出一个sql,这就是懒加载模式,分步查询时,在不适使用关联表的信息时就不会尽心查询。

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

<association property="dept" 
            select="com.mybatis.mapper.DepartmentMapper.getDeptById"
            column="{id=dept_id,xx=xx}">
        </association>

对于 column=”{id=dept_id,xx=xx}” 中id表示getDeptById方法的参数,dept_id是第一步查询的id列。
<association > 标签还包含一个fetchType属性,这个可以设置抓取方式,即是懒加载还是立即加载。

  • 11
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值