0%

(四)MyBatis学习笔记-MyBatis映射器

下面显示的是元素的一些属性:
在这里插入图片描述

1. update元素和delete元素

  1. 首先在映射接口中添加用于更新和删除的方法

    1
    2
    3
    4
    //更新方法
    public boolean updateEmp(Employee emp);
    //删除方法
    public boolean deleteEmpById(Integer id);
  2. 然后在映射器文件中添加对应的sql配置信息

    1
    2
    3
    4
    5
    6
    7
    <!-- 参数类型可以省略 -->
    <update id="updateEmp" parameterType="com.atguigu.mybatis.bean.Employee">
    update tbl_employee set last_name=#{lastName},gender=#{gender},email=#{email} where id=#{id}
    </update>
    <delete id="deleteEmpById">
    delete from tbl_employee where id=#{id}
    </delete>
  3. 进行测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    @Test
    public void test02() throws IOException {
    //1.根据MyBatis的配置文件,即mybatis-config.xml创建SqlSessionFactory
    SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
    //2.获取session实例,能直接执行*已经映射的SQL语句*
    SqlSession session = sqlSessionFactory.openSession(false);//设置默认不提交
    try {
    //3.获取接口的实现类对象
    EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);

    //4.测试删除方法
    boolean isDelete = employeeMapper.deleteEmpById(3);//输出true或者false
    System.out.println(isDelete);

    //5.手动提交
    session.commit();
    } finally {
    //4.关闭会话session
    session.close();
    }
    }

2. insert元素-插入语句

2.1 简单应用

  1. 首先在映射接口中添加用于插入的方法

    1
    2
    //增加方法
    public void addEmp(Employee emp);
  2. 然后在映射器文件中添加对应的sql配置信息

    1
    2
    3
    <insert id="addEmp">
    insert into tbl_employee(last_name,gender,email) values(#{lastName},#{gender},#{email})
    </insert>
  3. 测试代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    @Test
    public void test02() throws IOException {
    //1.根据MyBatis的配置文件,即mybatis-config.xml创建SqlSessionFactory
    SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
    //2.获取session实例,能直接执行*已经映射的SQL语句*
    SqlSession session = sqlSessionFactory.openSession(false);//设置默认不提交
    try {
    //3.获取接口的实现类对象
    EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
    //4.测试添加
    Employee emp = new Employee(null, "张三", "1", "zhangsan@gmail.com");
    employeeMapper.addEmp(emp);
    //5.手动提交
    session.commit();
    } finally {
    //4.关闭会话session
    session.close();
    }
    }

2.2 获取自增主键的值

MySQL支持自增主键,自增主键值的获取,MyBatis也是利用statement.getGenreatedKey();

MyBatis使用insert元素的useGenreatedKeys=”true”来使用自增主键获取主键值策略;
使用insert元素的keyProperty来指定对应的主键属性,也就是MyBatis获取到主键值以后,将这个值封装给javaBean的对应属性。

  1. 修改映射器文件中的insert元素

    1
    2
    3
    <insert id="addEmp" useGeneratedKeys="true" keyProperty="id">
    insert into tbl_employee(last_name,gender,email) values(#{lastName},#{gender},#{email})
    </insert>
  2. 测试代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    @Test
    public void test02() throws IOException {
    //1.根据MyBatis的配置文件,即mybatis-config.xml创建SqlSessionFactory
    SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
    //2.获取session实例,能直接执行*已经映射的SQL语句*
    SqlSession session = sqlSessionFactory.openSession(false);//设置默认不提交
    try {
    //3.获取接口的实现类对象
    EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
    //4.测试添加
    Employee emp = new Employee(null, "张三", "1", "zhangsan@gmail.com");
    employeeMapper.addEmp(emp);
    //输出员工的id
    System.out.println(emp.getId());
    //5.手动提交
    session.commit();
    } finally {
    //4.关闭会话session
    session.close();
    }
    }

3. select元素-查询语句

3.1 参数处理

3.1.1单个参数

比如我要根据employee的id值来查询对应的员工,这时候对应的查询方法的参数只有一个,就是id值。在映射器中的对应SQL语句中,#{参数名}中的参数名MyBatis不做特殊处理,也就是该参数名可以随便取名。
在这里插入图片描述

3.1.2 多个参数

3.1.2.1 使用注解传递多个参数
  1. 首先在映射接口中定义如下方法

    1
    2
    //根据员工id和姓名查询员工
    public Employee gerEmpByIdAndName(Integer id, String lastName);
  2. 然后在映射器文件中配置如下SQL

    1
    2
    3
    <select id="gerEmpByIdAndName" resultType="com.atguigu.mybatis.bean.Employee">
    select id,last_name,gender,email from tbl_employee where id=#{id} and last_name=#{lastName}
    </select>
  3. 运行测试之后会报如下错误

    1
    Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [0, 1, param1, param2]

    MyBatis在处理传入的多个参数时,会将多个参数封装成一个Map集合,对应的键值为:
    key:param1…paramN,或者参数的索引0…N
    value:我们传入的参数值
    #{}就是从map中获取指定的key值,所以我们应该传入key值而不是value值。

解决:
使用命名参数,即明确指定封装参数时map的key,封装后的map集合的key值为使用@Param注解指定的值,value为参数值。

修改映射接口,指定map集合的键即可:

1
2
//根据员工id和姓名查询员工
public Employee gerEmpByIdAndName(@Param("id")Integer id, @Param("lastName")String lastName);
3.1.2.2 通过POJO传递多个参数
  1. 存在一个POJO-Employee
    在这里插入图片描述

  2. 此时在映射接口定义如下方法:

    1
    2
    //根据POJO查询员工
    public Employee getEmpByBean(Employee emp);
  3. 在映射器配置如下SQL语句,这里是通过传入的Java Bean的id和lastName来查询。

    1
    2
    3
    <select id="getEmpByBean" resultType="com.atguigu.mybatis.bean.Employee">
    select id,last_name,gender,email from tbl_employee where id=#{id} and last_name=#{lastName}
    </select>
  4. 测试代码
    在这里插入图片描述

    3.1.2.3 通过Map集合传递多个参数
  5. 在映射接口定义如下方法

    1
    2
    //根据Map集合来查询员工
    public Employee getEmpByMap(Map<String, Object> map);
  6. 在映射器中配置SQL信息

    1
    2
    3
    <select id="getEmpByMap" resultType="com.atguigu.mybatis.bean.Employee">
    select id,last_name,gender,email from tbl_employee where id=#{id} and last_name=#{lastName}
    </select>
  7. 测试代码
    在这里插入图片描述

    3.1.2.4 混合使用

    在这里插入图片描述
    注意:集合和数组都有默认的key。

    3.2 #{}与${}的异同

    相同点:两者都可以获取map中的值或者pojo对象属性的值。
    不同点:

  8. #{}是以预编译的形式,将参数设置到sql语句中,类似于PreparedStatement,它可以防止sql注入。

  9. ${}是直接将取出的值拼接在sql语句中,类似于Statement,可能引发安全问题。

    下面演示一下:

    1. 映射器文件的sql配置如下:
      1
      2
      3
      <select id="getEmpByMap" resultType="com.atguigu.mybatis.bean.Employee">
      select id,last_name,gender,email from tbl_employee where id=#{id} and last_name=#{lastName}
      </select>
  10. 测试代码

    1
    2
    3
    4
    5
    6
    7
    EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
    //4.测试查询方法
    Map<String,Object> map = new HashMap<>();
    map.put("id", "1");
    map.put("lastName", "Tom");
    Employee emp = employeeMapper.getEmpByMap(map);
    System.out.println(emp);
  11. 运行结果
    在这里插入图片描述
    从输出的sql语句可以看出占位符?是存在的。

下面我们修改一下映射器文件的配置信息,更改为id=${id}:

1
2
3
<select id="getEmpByMap" resultType="com.atguigu.mybatis.bean.Employee">
select id,last_name,gender,email from tbl_employee where id=${id} and last_name=#{lastName}
</select>

再次测试的输出结果为:
在这里插入图片描述

3.3 ${}的更多用法

比如我们需要按照年份进行分表拆分,然后使用传入的年份生成对应的表名,如

1
select * from ${year}_salary where xxx;

又比如我们通过字段名来对表的字段进行排序,那么我们也可以通过$来实现。如

1
select * from tbl_employee order by ${last_name} ${order}

显然,原生JDBC不支持占位符的地方我们就可以使用${}来进行取值。

3.4 #{}的更多用法

#{}还可以规定参数的一些规则,比如javaType、 jdbcType、 mode、 numericScale、
resultMap、 typeHandler、 jdbcTypeName。

下面来讲一下jdbcType的用法。

在我们数据为null的时候,有些数据库可能不能识别mybatis对null的默认处理(MyBatis默认将null设置为OTHER类型),比如Oracle数据库就无法识别OTHER类型。

我们可以在某个插入为null的数据来使用jdbcType设置。比如我要进入如下数据库操作:

1
2
3
<insert id="addEmp" useGeneratedKeys="true" keyProperty="id">
insert into tbl_employee(last_name,gender,email) values(#{lastName},#{gender},#{email})
</insert>

但是我在传入数据的时候,email的值是null,那么Oracle数据库是无法识别而报错的。我们可以更改为如下语句则可以解决这个问题:
在这里插入图片描述
上面的配置只使用单条sql语句。我们可以在全局配置文件设置settings来实现全局配置,即:
在这里插入图片描述

3.5 查询返回数据封装

3.5.1 List封装查询到的数据

  1. 在映射接口编写查询方法

    1
    2
    //使用List封装查询到的数据
    public List<Employee> getEmpsByLastNameLike(String lastName);
  2. 在映射器文件中编写指定的SQL配置,注意:返回类型是Employee对象

    1
    2
    3
    <select id="getEmpsByLastNameLike" resultType="com.atguigu.mybatis.bean.Employee">
    select id,last_name,gender,email from tbl_employee where last_name like #{lastName}
    </select>
  3. 测试代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    @Test
    public void test04() throws IOException {
    //1.根据MyBatis的配置文件,即mybatis-config.xml创建SqlSessionFactory
    SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
    //2.获取session实例,能直接执行*已经映射的SQL语句*
    SqlSession session = sqlSessionFactory.openSession(false);//设置默认不提交
    try {
    //3.获取接口的实现类对象
    EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
    //4.查询
    List<Employee> empsList = employeeMapper.getEmpsByLastNameLike("%张%");
    for (Employee employee : empsList) {
    System.out.println(employee);
    }
    //5.手动提交
    session.commit();
    } finally {
    //4.关闭会话session
    session.close();
    }
    }

3.5.2 Map封装查询到的数据

需求1:将Employee中的属性封装到一个Map中,其中key为Employee中的属性名,value为对应的值。

  1. 编写映射接口方法

    1
    2
    //使用Map封装查询到的数据
    public Map<String, Object> getEmpsByIdReturnMap(Integer id);
  2. 在映射器文件编写对应的SQL配置

    1
    2
    3
    4
    <!--  返回类型是Map集合,map是系统自定义的别名 -->
    <select id="getEmpsByIdReturnMap" resultType="map">
    select * from tbl_employee where id=#{id}
    </select>
  3. 测试代码

    1
    2
    3
    4
    EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
    //4.查询
    Map<String, Object> empMap = employeeMapper.getEmpsByIdReturnMap(1);
    System.out.println(empMap);
  4. 运行结果

    1
    {gender=1, last_name=Tom, id=1, email=shotozheng@gmail.com}

    需求2:将多个Employee对象封装到Map集合中,其中key为Employee中的id属性值,value为Employee对象。

  5. 同样需要在映射接口编写方法

    1
    2
    @MapKey("id")
    public Map<Integer,Employee> getEmpsByLastNameLikeReturnMap(String lastName);

    注意:MapKey在于指定返回的Map集合的key为Employee的属性id

  6. 在映射器接口编写SQL配置

    1
    2
    3
    4
    <!--  注意:这里的返回类型是Employee对象 -->
    <select id="getEmpsByLastNameLikeReturnMap" resultType="com.atguigu.mybatis.bean.Employee">
    select * from tbl_employee where last_name like #{lastName}
    </select>
  7. 运行测试即可,不再赘述。

4. resultMap元素

比如我们在定义Java Bean时,POJO的属性名若与数据库表的字段名不一样则会导致查询出来的数据为null。我们之前是用通过给SQL的的字段命和POJO对应属性一样的名称或者通过驼峰命名法来处理这个问题。但是这些可能会导致SQL语句不好理解或者POJO中的属性名不符合驼峰命名法规范等问题。

那么现在我们可以使用resultMap来定义映射规则来处理这个问题,当然它还可以进行级联更新和定制类型转化器等功能。定义映射规则就是SQL到Java Bean的映射关系定义。

下面演示一下resultMap自定义结果的功能:

  1. 创建一个POJO类Employee

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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;
    }
    //getter,setter,toString....
    }

    注意:类中lastName属性对应的数据库表tbl_employee字段last_name

  2. 在映射接口EmployeePlus中定义如下方法

    1
    public Employee getEmpById(Integer id);
  3. 在映射器文件EmployeePlus.xml文件定义如下SQL配置
    在这里插入图片描述

  4. 测试代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    @Test
    public void test05() throws IOException {
    //1.根据MyBatis的配置文件,即mybatis-config.xml创建SqlSessionFactory
    SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
    //2.获取session实例,能直接执行*已经映射的SQL语句*
    SqlSession session = sqlSessionFactory.openSession(false);//设置默认不提交
    try {
    //3.获取接口的实现类对象
    EmployeeMapperPlus mapper = session.getMapper(EmployeeMapperPlus.class);
    //4.查询
    Employee emp = mapper.getEmpById(1);
    System.out.println(emp);
    //5.手动提交
    session.commit();
    } finally {
    //4.关闭会话session
    session.close();
    }
    }
  5. 运行结果
    在这里插入图片描述
    在进行了自定义映射配置之后,即使Java Bean的属性名与数据库表的字段不一样,也可以形成映射关系。

5. 关联查询

需求:在查询出员工对象的同时,查询出该员工所在的部门。

5.1 级联属性封装结果集

  1. 创建两个Java Bean,分别为员工类Employee和部门类Department

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    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;
    }
    //getter,setter,toString
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class Department {
    private Integer id; //部门编号
    private String departmentName; //部门名称

    public Department() {
    super();
    }

    public Department(Integer id, String departmentName) {
    super();
    this.id = id;
    this.departmentName = departmentName;
    }
    //getter,setter,toString....
    }
  2. 创建对应的数据库表tbl_employee和tbl_dept

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE tbl_employee (
    id int(11) NOT NULL AUTO_INCREMENT,
    last_name varchar(255) DEFAULT NULL,
    gender char(1) DEFAULT NULL,
    email varchar(255) DEFAULT NULL,
    d_id int(11) DEFAULT NULL,
    PRIMARY KEY (id),
    KEY FK_tbl_employee (d_id),
    CONSTRAINT FK_tbl_employee FOREIGN KEY (d_id) REFERENCES tbl_dept (id)
    )
    1
    2
    3
    4
    CREATE TABLE tbl_dept(
    id INT(11) PRIMARY KEY AUTO_INCREMENT,
    dept_name VARCHAR(255)
    )
  3. 映射接口EmployeeMapperPlus中定义如下方法

    1
    public Employee getEmpAndDept(Integer id);
  4. 映射器文件EmployeeMapperPlus.xml进行如下配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <!-- 联合查询,**级联属性封装结果集** -->
    <resultMap type="com.atguigu.mybatis.bean.Employee" id="MyDifEmp">
    <id column="id" property="id"/>
    <result column="last_name" property="lastName"/>
    <result column="gender" property="gender"/>
    <result column="email" property="email"/>
    <!-- 下面的是关于部门表的内容,可以使用Employee的属性dept来引用 -->
    <result column="did" property="dept.id"/>
    <result column="dept_name" property="dept.departmentName"/>
    </resultMap>
    <!-- 查询两个表的所有字段的值 resultMap的值即为上方resultMap元素的id-->
    <select id="getEmpAndDept" resultMap="MyDifEmp">
    SELECT e.id id, e.last_name last_name,e.gender gender, e.email email,
    e.d_id d_id, d.id did, d.dept_name dept_name FROM tbl_employee e, tbl_dept d
    WHERE e.d_id=d.id AND e.id=#{id}
    </select>
  5. 运行测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    @Test
    public void test05() throws IOException {
    //1.根据MyBatis的配置文件,即mybatis-config.xml创建SqlSessionFactory
    SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
    //2.获取session实例,能直接执行*已经映射的SQL语句*
    SqlSession session = sqlSessionFactory.openSession(false);//设置默认不提交
    try {
    //3.获取接口的实现类对象
    EmployeeMapperPlus mapper = session.getMapper(EmployeeMapperPlus.class);
    //4.查询
    Employee emp = mapper.getEmpAndDept(1);
    System.out.println(emp);//连同部门信息也会打印出来
    //5.手动提交
    session.commit();
    } finally {
    //4.关闭会话session
    session.close();
    }
    }

    刚才对映射器文件EmployeeMapperPlus.xml进行配置时使用的是级联属性封装结果集 的方式,下面我们也可以使用association的方式来定义关联的单个对象的封装规则。

    5.2 association元素

    5.2.1 association嵌套结果集

    在原有的基础上,对映射器文件EmployeeMapperPlus.xml的resultMap元素进行如下更改配置:
    在这里插入图片描述

    5.2.2 association分步查询

    我们还可以使用association来进行分步查询。

具体思路:

  1. 先按照员工的id去查询员工的信息
  2. 根据查询员工信息中的d_id值去部门表查出部门信息
  3. 将查询到的部门信息设置到员工信息中

具体步骤:

  1. 为了根据员工的id去查询员工的信息,我们需要先在映射接口EmployeeMapperPlus中定义如下方法:

    1
    public Employee getEmpByIdStep(Integer id);
  2. 然后需要在映射器文件EmployeeMapperPlus.xml文件进行如下配置

    1
    2
    3
    4
    <!-- 查出员工的信息 -->
    <select id="getEmpByIdStep" resultMap="MyEmpByStep">
    select * from tbl_employee where id=#{id}
    </select>
  3. 因为需要根据员工信息中的d_id值去部门表查出部门信息 ,所以现在需要在映射接口DepartmentMapper中定义如下方法:

    1
    public Department getDeptById(Integer id);
  4. 同样地,在映射器文件中进行如下配置:

    1
    2
    3
    4
    5
    <mapper namespace="com.atguigu.mybatis.mapper.DepartmentMapper">
    <select id="getDeptById" resultType="com.atguigu.mybatis.bean.Department">
    select id,dept_name departmentName from tbl_dept where id=#{id}
    </select>
    </mapper>
  5. 对映射器文件EmployeeMapperPlus.xml做如下的resultMap元素配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <resultMap type="com.atguigu.mybatis.bean.Employee" id="MyEmpByStep">
    <!-- 员工基本属性信息映射配置 -->
    <id column="id" property="id"/>
    <result column="last_name" property="lastName"/>
    <result column="email" property="email"/>
    <result column="gender" property="gender"/>

    <!-- association定义关联对象的封装规则
    property的内容的Employee关联的对象属性名dept
    select表明当前属性调用select指定的方法查出的结果,内容的namespace+方法id
    column指定将哪一列的值传给这个方法,这里要根据d_id去查询部门信息,所以为d_id
    流程:使用select指定的方法并通过传入column指定的这列参数的值去查出对象,
    并封装给property指定的属性,即dept
    -->
    <association property="dept"
    select="com.atguigu.mybatis.mapper.DepartmentMapper.getDeptById"
    column="d_id">
    </association>
    </resultMap>
  6. 运行测试
    在这里插入图片描述

    5.2.3 延迟加载问题

    从以上的输出结果可以知道,系统会进行通过员工id查询员工信息,并且通过员工的id去查询对应的部门号。但是如果我们在未使用到部门的信息时,也就是我们只输出员工本身的一些与部门无关的信息,系统依旧会进行部门信息的查询。这样会浪费系统资源,我们可以通过设置延迟加载来处理这个问题。

在全局配置文件进行如下配置:

1
2
3
<!-- 开启延迟加载和关闭属性按需加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>

5.3 collection元素

需求:根据id查询部门的时候,同时查询出该部门的所有员工。

5.3.1 collection嵌套结果集

  1. 更改JavaBean类Department,增加字段以及对应的getter和setter方法。具体如下所示:
    在这里插入图片描述

  2. 在映射接口DepartmentMapper中添加如下方法

    1
    public Department getDeptAndEmpsByDeptId(Integer id);
  3. 在映射器文件DepartmentMapper.xml进行如下配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <!-- type的内容即为返回值类型,即查询到的部门对象 -->
    <resultMap type="com.atguigu.mybatis.bean.Department" id="MyDept">
    <id column="did" property="id"/>
    <result column="dept_name" property="departmentName"/>
    <!-- collection定义关联集合类型的属性的封装规则
    ofType指定集合里面的元素类型
    -->
    <collection property="emps" ofType="com.atguigu.mybatis.bean.Employee">
    <!-- 定义这个集合中元素的封装规则,这里的是员工 -->
    <id column="eid" property="id"/>
    <result column="last_name" property="lastName"/>
    <result column="email" property="email"/>
    <result column="gender" property="gender"/>
    </collection>
    </resultMap>
    <select id="getDeptAndEmpsByDeptId" resultMap="MyDept">
    select d.id did,d.dept_name,e.id eid,e.last_name,e.email,e.gender
    from tbl_dept d
    LEFT JOIN tbl_employee e
    ON d.id=e.d_id
    WHERE d.id=#{id}
    </select>
  4. 测试代码
    在这里插入图片描述

    5.3.2 collection分步查询

    具体思路:

  5. 先按照部门的id去查询部门的信息

  6. 根据查询到的部门信息中的id值去查询员工表的员工信息

  7. 将查询到的员工信息设置到部门信息的属性集合中

具体步骤:

  1. 在映射接口文件DepartmentMapper中定义如下方法,即根据部门id查询部门信息:

    1
    public Department getDeptByIdStep(Integer id);
  2. 在映射器文件DepartmentMapper.xml进行如下配置:

    1
    2
    3
    <select id="getDeptByIdStep" resultMap="MyDeptStep">
    select id,dept_name departmentName from tbl_dept where id=#{id}
    </select>
  3. 在映射接口EmployeeMapperPlus中定义如下方法,即根据部门id查询所有员工:

    1
    public List<Employee> getEmpsByDeptId(Integer deptId);
  4. 在映射器EmployeeMapperPlus.xml中配置如下信息

    1
    2
    3
    4
    5
    <!--注意:如果Employee中的字段与数据库表的字段名不一样,需要给字段命和POJO中对应属性一样的名称,
    比如下面的last_name字段必须需命名为lastName,否则无法完成一一映射。-->
    <select id="getEmpsByDeptId" resultType="com.atguigu.mybatis.bean.Employee">
    select id,last_name lastName,gender,email from tbl_employee where d_id=#{deptId}
    </select>
  5. 在映射器文件DepartmentMapper.xml中配置resultMapper信息,完成关联对象的封装规则:
    在这里插入图片描述

补充:我们上面的例子只在column属性中传递了一个部门的id值。如下图示:
在这里插入图片描述
我们在分步查询时也可以进行多列传值,MyBatis会将多列的值封装为map进行传递。
格式为column=”{key1=column1,key2=column2}”

比如可以写成如下形式:
在这里插入图片描述
其中的键deptId对应映射器EmployeeMapperPlus.xml中的SQL的传入的id名称。即
在这里插入图片描述

6. sql 元素

sql元素的作用在于可以定义一条SQL的一部分,方便后面的SQL引用它。假设映射器文件中有如下配置信息:
在这里插入图片描述
我们可以使用sql将其中的id,last_name lastName,gender,email抽取出来。如下所示:
在这里插入图片描述
更改原有的配置信息,引用sql标签的配置。
在这里插入图片描述
sql元素还支持变量的传递,映射器的配置信息如下:
在这里插入图片描述
在include元素中定义了一个命名为e的变量,其值是SQL中标tbl_employee的别名emp,然后sql元素就能够使用这个变量名了。这个用法常用于多表查询并需要给不同表起别名的情况。

------ 本文结束------