MyBatis笔记 | 详解resultType和resultMap

resultType

从这条语句中返回的期望类型的类的完全限定名或别名,注意如果是集合,那应该是集合可以包含的类型,而不能是集合本身。
下面我们来讨论其返回List和Map的情况:

(1)select返回List

在select元素中,如果返回的是一个集合,要在sql映射中写集合中元素的类型。

我们想实现通过名字来进行模糊查询,返回Employee类型的List集合。

public List<Employee> getEmpsByLastNameLike(String lastName);

然后我们在sql映射文件中配置如下:

<select id="getEmpsByLastNameLike" resultType="com.cerr.mybatis.Employee">
        select * from tb1_employee where last_name like #{lastName}
</select>

注意resultType填入的是Employee的类型而不是List类型。

测试方法,查询名字带有e的:

package com.cerr.mybatis;
import com.cerr.mybatis.dao.EmployeeMapper;
import com.cerr.mybatis.dao.EmployeeMapperAnnotation;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
public class MyBatisTest {

    //获取SQLSessionFactory
    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        return new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void test9() throws IOException {
        //获取SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        //获取SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            //获取接口的实现类对象:会为接口自动的创建一个代理对象,代理对象去执行增删改查
            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);

            //调用方法
            List<Employee> list = employeeMapper.getEmpsByLastNameLike("%e%");
            for (Employee employee : list){
                System.out.println(employee);
            }

        }finally {
            //关闭
            sqlSession.close();
        }
    }
}

结果:


(2)select记录封装Map

有两种情况,一种是返回单个实体类的Map;另一种是返回多个实体类的Map。

(3)返回单个实体类的Map

如果返回的是单个实体类的Map,那么在select元素中的resultType的值就是map

我们想返回的Map是key为记录的列名,值为记录的值。我们首先在接口中定义一个方法:

public Map<String,Object> getEmpByIdReturnMap(Integer id);

然后在sql映射文件中给予配置,注意resultType的值是map

package com.cerr.mybatis;

import com.cerr.mybatis.dao.EmployeeMapper;
import com.cerr.mybatis.dao.EmployeeMapperAnnotation;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.*;

public class MyBatisTest {

    //获取SQLSessionFactory
    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        return new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void test8() throws IOException {
        //获取SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        //获取SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            //获取接口的实现类对象:会为接口自动的创建一个代理对象,代理对象去执行增删改查
            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
            Map<String,Object> map = employeeMapper.getEmpByIdReturnMap(1);
            System.out.println(map);
        }finally {
            //关闭
            sqlSession.close();
        }
    }
}

(4)返回多个实体类的Map

我们想返回多个实体类的Map的话,那么resultType的值应该是实体类,而不是map本身。

我们想返回多个Employee组成的Map,key为Employee中的id顺序,在这里我们需要使用到@MapKey注解来指明我们要封装哪个属性为Map的key,值是Employee对象,我们先在接口中定义方法:

    //告诉MyBatis封装这个Map的时候使用哪个属性作为Map的key
    @MapKey("id")
    public Map<Integer,Employee> getEmpByLastNameReturnMap(String lastName);

SQL 映射文件:

    <select id="getEmpByLastNameReturnMap" resultType="com.cerr.mybatis.Employee">
        select * from tb1_employee where last_name like #{lastName}
    </select>

测试方法:

public class MyBatisTest {

    //获取SQLSessionFactory
    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        return new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void test9() throws IOException {
        //获取SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        //获取SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            //获取接口的实现类对象:会为接口自动的创建一个代理对象,代理对象去执行增删改查
            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);

            Map<Integer,Employee> map = employeeMapper.getEmpByLastNameReturnMap("%e%");
            System.out.println(map);
        }finally {
            //关闭
            sqlSession.close();
        }
    }
}

结果:



resultMap

(1)通过resultMap实现高级结果映射集

其属性如下:

  • type:自定义规则的Java类型
  • id:唯一id方便引用
<mapper namespace="com.cerr.mybatis.dao.EmployeeMapperPlus">
    <!-- 定义封装规则 -->
    <resultMap id="myEmp" type="com.cerr.mybatis.Employee">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="email" property="email"/>
        <result column="gender" property="gender"/>
    </resultMap>
    <select id="getEmpById" resultMap="myEmp">
        select * from tb1_employee where id = #{id}
    </select>
</mapper>

上述代码中,<id>子标签指定主键列的封装规则。

  • column:指定哪一列
  • property:指定对应的JavaBean属性

<result>子标签定义普通列的封装规则,属性与<id>的属性用法一致。对于主键来说也可以使用<result>定义规则,但是使用<id>定义主键会有底层优化,所以我们推荐主键使用<id>标签来定义

定义好规则后,<resultMap>idmyEmp,这个id可供下面的<select>标签引用,即resultMap="myEmp"

测试方法如下:

package com.cerr.mybatis;
import com.cerr.mybatis.dao.EmployeeMapper;
import com.cerr.mybatis.dao.EmployeeMapperAnnotation;
import com.cerr.mybatis.dao.EmployeeMapperPlus;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
public class MyBatisTest {
    //获取SQLSessionFactory
    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        return new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void test10() throws IOException {
        //获取SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        //获取SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            //获取接口的实现类对象:会为接口自动的创建一个代理对象,代理对象去执行增删改查
            EmployeeMapperPlus mapper = sqlSession.getMapper(EmployeeMapperPlus.class);
            Employee employee = mapper.getEmpById(1);
            System.out.println(employee);
        }finally {
            //关闭
            sqlSession.close();
        }
    }

(2)使用resultMap进行关联查询

首先我们定义一个Department类并且新建一张表:

/**新建表**/
create table tbl_dept(
    id int(11) primary key auto_increment,
    dept_name varchar(255)
)
/**对tb1_employee表新增一列**/
alter table tb1_employee add column d_id int(11);
/**新增外键**/
alter table tb1_employee add constraint fk_emp_dept foreign key(d_id) 
    references tbl_dept(id);
package com.cerr.mybatis;
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 + '\'' +
                '}';
    }
}

(3)使用级联属性封装结果来进行关联查询

EmployeeMapperPlus接口中新增一个方法:

public Employee getEmpAndDept(Integer id);

SQL映射文件配置如下,在resultMap中使用department.id这种级联写法来封装结果集:

    <resultMap id="myDifEmp" type="com.cerr.mybatis.Employee">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <result column="did" property="department.id"/>
        <result column="dept_name" property="department.departmentName"/>
    </resultMap>
    <select id="getEmpAndDept" resultMap="myDifEmp">
        select e.id id ,e.last_name last_name ,e.gender gender ,e.email email,d.id did,d.dept_name dept_name from
         tb1_employee e,tbl_dept d where e.d_id=d.id and e.id = #{id}
    </select>

(4)使用association定义关联对象封装规则

我们也可以使用<association><association>可以指定联合的JavaBean对象,其中的property属性指定哪个属性是联合的对象,javaType属性指定这个属性对象的类型。
示例如下:

    <resultMap id="myDifEmp2" type="com.cerr.mybatis.Employee">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
 
        <association property="department" javaType="com.cerr.mybatis.Department">
            <id column="did" property="id"/>
            <result column="dept_name" property="departmentName"/>
        </association>
    </resultMap>
    <select id="getEmpAndDept" resultMap="myDifEmp2">
        select e.id id ,e.last_name last_name ,e.gender gender ,e.email email,d.id did,d.dept_name dept_name from
         tb1_employee e,tbl_dept d where e.d_id=d.id and e.id = #{id}
    </select>

(5)使用association进行分步查询

对于上面的关联对象查询中,我们可以将其分解为两步,其SQL如下:

select * from tb1_employee where id = ?
select id,dept_name departmentName from tbl_dept where id = ?

即先通过id在tb1_employee表中查出信息,并且该记录中有一个d_id字段,我们将该字段作为第二条sql语句的参数去tbl_dept表中查出记录,并把该记录封装成Department,然后赋值给Employeedepartment属性。此时就可以用到我们的分步查询。

EmployeeMapper接口中新增一个方法:

public Employee getEmpByIdStep(Integer id);

我们新建一个DepartmentMapper接口:

package com.cerr.mybatis.dao;

import com.cerr.mybatis.Department;

public interface DepartmentMapper {

    public Department getDeptById(Integer id);
}

然后新建一个SQL映射文件DepartmentMapper.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">
<mapper namespace="com.cerr.mybatis.dao.DepartmentMapper">
    <!--
        1.先按照员工id查询员工信息
        2.根据查询员工信息中的d_id去部门表查出部门信息
        3.部门设置到员工中
    -->
    <resultMap id="myEmpByStep" type="com.cerr.mybatis.Employee">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <result column="email" property="email"/>
        <!--
            流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性
        -->
        <association property="department"
                     select="com.cerr.mybatis.dao.DepartmentMapper.getDeptById"
                     column="d_id">
        </association>
    </resultMap>
    <select id="getEmpByIdStep" resultMap="myEmpByStep">
        select * from tb1_employee where id = #{id}
    </select>
</mapper>

上述配置使用了association标签来配置分步查询的方法,select属性表明当前属性是调用select指定的方法查出的结果,要填入该方法的完整名字(包括全类名)。column属性指定将哪一列的值传给这个方法。

测试方法:

package com.cerr.mybatis;
import com.cerr.mybatis.dao.EmployeeMapper;
import com.cerr.mybatis.dao.EmployeeMapperAnnotation;
import com.cerr.mybatis.dao.EmployeeMapperPlus;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
public class MyBatisTest {

    //获取SQLSessionFactory
    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        return new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void test12() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapperPlus mapper = sqlSession.getMapper(EmployeeMapperPlus.class);
            Employee employee = mapper.getEmpByIdStep(1);
            System.out.println(employee);
            System.out.println(employee.getDepartment());
        }finally {
            //关闭
            sqlSession.close();
        }
    }
}

结果如下:

延迟加载

我们上述方法查询的时候,每次查询Employee对象的时候,都将Department一起查询出来了,而我们想将部门信息等到我们要使用的时候再去查询。只需要在上述的分步查询的基础上在全局配置文件中配置lazyLoadingEnabledaggressiveLazyLoading即可。

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

我们修改上面分步查询中的测试方法,不使用到department字段:

    @Test
    public void test12() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapperPlus mapper = sqlSession.getMapper(EmployeeMapperPlus.class);
            Employee employee = mapper.getEmpByIdStep(1);
            System.out.println(employee.getEmail());
        }finally {
            //关闭
            sqlSession.close();
        }
    }

在控制台中看其SQL的信息(此处使用了log4j,详情看这篇文章:MyBatis | 使用log4j在控制台输出SQL语句):
没有查询Department表:


若需要使用到department字段时:

@Test
    public void test12() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapperPlus mapper = sqlSession.getMapper(EmployeeMapperPlus.class);
            Employee employee = mapper.getEmpByIdStep(1);
            System.out.println(employee.getEmail());
            System.out.println(employee.getDepartment());
        }finally {
            //关闭
            sqlSession.close();
        }
    }

(6)使用collection定义关联的集合类型元素的封装规则

例如我们案例中,对于一个Department类中,嵌套了一个Employee类型的集合,那么我们想在查询Department的时候顺便将其集合元素查询出来,我们就可以通过使用collection嵌套结果集的方式,定义关联的集合类型元素的封装规则。

collection标签:定义关联集合类型的属性的封装规则,其有两个比较重要的属性:

  • property:定义关联集合类型的属性的封装规则
  • ofType:指定集合里面元素的类型

我们先在Department类中加入集合元素

private List<Employee> emps;

再加入对应的getter/setter,还有重写toString()

    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 + '\'' +
                ", emps=" + emps +
                '}';
    }

DepartmentMapper接口中新增方法:

public Department getDeptByIdPlus(Integer id);

SQL映射文件配置:

<resultMap id="myDept" type="com.cerr.mybatis.Department">
        <id column="did" property="id"/>
        <result column="dept_name" property="departmentName"/>
        <!-- 员工 : 集合类型-->
        <collection property="emps" ofType="com.cerr.mybatis.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="getDeptByIdPlus" resultMap="myDept">
        select d.id did,d.dept_name dept_name,e.id eid,e.last_name last_name
                ,e.email email,e.gender gender
        from tbl_dept d
        left join tb1_employee e
        on d.id = e.d_id
        where d.id = #{id}
    </select>

测试方法:

package com.cerr.mybatis;
import com.cerr.mybatis.dao.DepartmentMapper;
import com.cerr.mybatis.dao.EmployeeMapper;
import com.cerr.mybatis.dao.EmployeeMapperAnnotation;
import com.cerr.mybatis.dao.EmployeeMapperPlus;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
public class MyBatisTest {

    //获取SQLSessionFactory
    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        return new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void test13() throws IOException {
        SqlSessionFactory factory = getSqlSessionFactory();
        SqlSession session = factory.openSession();
        try{
            DepartmentMapper mapper = session.getMapper(DepartmentMapper.class);
            Department department = mapper.getDeptByIdPlus(1);
            System.out.println(department);
            System.out.println(department.getEmps());
        }finally {
            session.close();
        }
    }
}

结果:


(7)使用collection定义关联的集合元素分步查询

这个与association进行分步查询的结果类似,只是association是针对单个元素,而collection针对集合元素。
对于上面使用collection定义关联的集合类型元素的封装规则中的代码中,我们可以拆分为:

select * from tbl_dept where id = ?;
select * from tb1_employee where d_id = ?;

既先查tbl_dept表中的记录,然后根据Departmentid字段的记录去tb1_employee表中查询符合条件的Employee记录,并封装成集合然后给Department包装。

EmployeeMapperPlus接口方法:

public List<Employee> getEmpsByDeptId(Integer deptId);

SQL映射文件EmployeeMapperPlus.xml

    <select id="getEmpsByDeptId" resultType="com.cerr.mybatis.Employee">
        select * from tb1_employee where d_id = #{deptId}
    </select>

DepartmentMapperPlus接口方法:

public Department getDeptByIdStep(Integer id);

SQL映射文件:

    <resultMap id="myDeptStep" type="com.cerr.mybatis.Department">
        <id column="id" property="id"/>
        <result column="dept_name" property="departmentName"/>
        <collection property="emps"
                    select="com.cerr.mybatis.dao.EmployeeMapperPlus.getEmpsByDeptId"
                    column="id"></collection>
    </resultMap>
    <select id="getDeptByIdStep" resultMap="myDeptStep">
        select id,dept_name departmentName from tbl_dept where id = #{id}
    </select>

测试方法:

package com.cerr.mybatis;
import com.cerr.mybatis.dao.DepartmentMapper;
import com.cerr.mybatis.dao.EmployeeMapper;
import com.cerr.mybatis.dao.EmployeeMapperAnnotation;
import com.cerr.mybatis.dao.EmployeeMapperPlus;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
public class MyBatisTest {

    //获取SQLSessionFactory
    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        return new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void test13() throws IOException {
        SqlSessionFactory factory = getSqlSessionFactory();
        SqlSession session = factory.openSession();
        try{
            DepartmentMapper mapper = session.getMapper(DepartmentMapper.class);
            Department department = mapper.getDeptByIdStep(1);
            System.out.println(department);
            System.out.println(department.getEmps());
        }finally {
            session.close();
        }
    }
}

结果:


collection的扩展

对于分步查询传递多列值的时候,可以将其值封装成map再传递进column属性。其格式如{key1=column1,key2=column2,...}
对于上面的配置文件,我们可以修改为column="{deptId=id}",具体配置如下:

    <resultMap id="myDeptStep" type="com.cerr.mybatis.Department">
        <id column="id" property="id"/>
        <result column="dept_name" property="departmentName"/>
        <collection property="emps"
                    select="com.cerr.mybatis.dao.EmployeeMapperPlus.getEmpsByDeptId"
                    column="{deptId=id}" fetchType="lazy"></collection>
    </resultMap>
    <select id="getDeptByIdStep" resultMap="myDeptStep">
        select id,dept_name departmentName from tbl_dept where id = #{id}
    </select>

collection中有一个fetchType属性,其有两种取值:

  • lazy:表示使用延迟加载
  • eager:表示使用立即加载

(8)使用discriminator鉴别器

MyBatis可以使用discriminator判断某列的值,然后根据某列的值改变其封装行为。

对于discriminator标签,有如下两个属性

  • column:指定判定的列名
  • javaType:指定列值对应的java类型

discriminator标签还有一个子标签case,其属性如下:

  • value:列的值
  • resultType:指定封装的结果类型

现在我们有一个要求,如果在查询Employee时,查出的是女生,就把部门信息查询出来,否则就不查询;如果是男生,就把last_name这一列的值赋值给email
这样的话,我们首先要使用<resultMap>标签进行自定义结果集封装,对于其他的列值,我们就依旧使用<id><result >标签来封装,对于gender属性我们使用<discriminator >来判定,SQL映射文件如下:

    <resultMap id="myEmpDis" type="com.cerr.mybatis.Employee">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <result column="email" property="email"/>
        <discriminator javaType="java.lang.String" column="gender">
            <!-- 女生 resultType:指定封装的结果类型 -->
            <case value="0" resultType="com.cerr.mybatis.Employee">
                <association property="department"
                             select="com.cerr.mybatis.dao.DepartmentMapper.getDeptById"
                             column="d_id">
                </association>
            </case>
            <!-- 男生 -->
            <case value="1" resultType="com.cerr.mybatis.Employee">
                <id column="id" property="id"/>
                <result column="last_name" property="lastName"/>
                <result column="gender" property="gender"/>
                <result column="last_name" property="email"/>
            </case>
        </discriminator>
    <select id="getEmpByIdStep" resultMap="myEmpDis">
        select * from tb1_employee where id = #{id}
    </select>

测试方法:

package com.cerr.mybatis;
import com.cerr.mybatis.dao.DepartmentMapper;
import com.cerr.mybatis.dao.EmployeeMapper;
import com.cerr.mybatis.dao.EmployeeMapperAnnotation;
import com.cerr.mybatis.dao.EmployeeMapperPlus;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
public class MyBatisTest {

    //获取SQLSessionFactory
    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        return new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void test12() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapperPlus mapper = sqlSession.getMapper(EmployeeMapperPlus.class);
            Employee employee = mapper.getEmpByIdStep(4);
            System.out.println(employee);
            System.out.println(employee.getDepartment());
        }finally {
            //关闭
            sqlSession.close();
        }
    }
}

上述代码中,id=4的Employee是女生,因此会查询Department:


我们将传入的id值改为1(男生),所以不会查询Department,所以获取其department值的时候是null,并且email的值与其lastName的值一样:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容