美文网首页Java
MyBatis笔记 | 详解resultType和resultM

MyBatis笔记 | 详解resultType和resultM

作者: 一颗白菜_ | 来源:发表于2019-11-28 21:41 被阅读0次

    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的值一样:

    相关文章

      网友评论

        本文标题:MyBatis笔记 | 详解resultType和resultM

        本文链接:https://www.haomeiwen.com/subject/azyiwctx.html