mybatis中的resultMap

mybatis中的resultMap,结果映射,将返回的数据进行更加高级的自定义规则设置,resultMap 元素是 MyBatis 中最重要最强大的元素

结果映射中还可以使用resultType,它可以指定返回的数据类型,如map

<select id="getEmp" resultType="map">
        select * from emp 
    </select>

映射到map中并不是很好的结果,因为我们不是很清晰的知道map中的数据,所有我们一般指定javabean类型返回,如上面的例子中,查询的emp数据,

我们写一个Emp类来进行参数的封窗。

@Data
public
class Emp { private Long id; private String name; private String gender; private String email; }

我们的xml就可以这样写:

<select id="getEmp" resultType="com.mybatis.bean.Emp">
        select id,name,gender,emailfrom emp 
</select>

上面使用resultType的做法,我们可以使用resultMap,实现相同的结果

  <!--id  唯一标识-->
    <resultMap id="myEmp" type="com.mybatis.bean.Emp">
            <id column="id" property="id"></id>
            <result column="name" property="name"></result>
            <result column="gender" property="gender"></result>
            <result column="email" property="email"></result>
    </resultMap>

   <select id="getEmp" resultMap="myEmp">
        select id,name,gender,email from emp
    </select>

resultType和resultMap不能同时使用,如果Emp中有一个对象的属性,那么直接使用resultType返回 com.mybatis.bean.Emp将会有问题;

如:Emp中有一个属性dept

@Data
public class Emp {
    private Long id;
    private String name;
    private String gender;
    private String email;
    private Dept dept;

Dept:

@Data
public class Dept {
    private Long deptId;
    private String deptName;

xml:

<select id="getEmpAndDept" resultType="com.mybatis.bean.Emp">
        SELECT e.id,e.name,e.gender,e.email,d.dept_id,d.dept_name  FROM emp e, dept d where e.dept_id = d.dept_id and e.id = #{id}
    </select>

这时候我们发现返回的数据中dept是null,所以这时候我们就可以使用resultMap自定义的映射规则了

第一种方式:

<!--id  唯一标识-->
    <resultMap id="myEmpDept" type="com.mybatis.bean.Emp">
            <id column="id" property="id"></id>
            <result column="name" property="name"></result>
            <result column="gender" property="gender"></result>
            <result column="email" property="email"></result>
            <result column="dept_id" property="dept.deptId"></result>
            <result column="dept_name" property="dept.deptName"></result>
    </resultMap>

第二种方式:使用association

    <resultMap id="myEmpDept" type="com.mybatis.bean.Emp">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <result column="gender" property="gender"></result>
        <result column="email" property="email"></result>
        <!--指定javabean对象,emp的属性dept
        property:指定emp的属性dept
        javaType:指定属性的类型com.mybatis.bean.Dept
        -->
        <association property="dept" javaType="com.mybatis.bean.Dept">
            <id column="dept_id" property="deptId"></id>
            <result column="dept_name" property="deptName"></result>
        </association>
    </resultMap>

SQL这里的resultMap指定上面的id属性

<select id="getEmpAndDept" resultMap="myEmpDept">
        SELECT e.id,e.name,e.gender,e.email,d.dept_id,d.dept_name  FROM emp e, dept d where e.dept_id = d.dept_id and e.id = #{id}
    </select>

这样就可以返回的dept就有数据了。

如果Dept中定义的类型是集合:一个部门对应多个员工

@Data
public class Dept {
    private Long deptId;
    private String deptName;
   private List<Emp> emp;

这时候使用association就不行了,需要使用collection

<resultMap id="myDepts" type="com.mybatis.bean.Dept">
        <id column="dept_id" property="deptId"></id>
        <result column="dept_name" property="deptName"></result>
        <!--property:Dept中的emp属性
                    ofType:集合里面元素的类型
                    -->
        <collection property="emp" ofType="com.mybatis.bean.Emp">
            <id column="id" property="id"></id>
            <result column="name" property="name"></result>
            <result column="gender" property="gender"></result>
            <result column="email" property="email"></result>
        </collection>
    </resultMap>

    <select id="getDept" resultMap="myDepts">
        select d.dept_id,d.dept_name ,e.id,e.name,e.gender,e.email from dept d
        LEFT JOIN emp e ON  d.dept_id = e.dept_id where d.dept_id = #{dept_id}
    </select>

 

关联的嵌套 Select 查询(分步查询):

同样的需求:查询一个部门中的多个员工

mapper中的接口:

//通过部门的id查询员工
public List<Emp> selectEmps(Integer dept_id);
//通过部门id查询部门
public Dept selectDept(Integer dept_id);

DeptMapper.xml;

 <!--分步查询-->
    <resultMap id="myDept" type="com.mybatis.bean.Dept">
        <id column="dept_id" property="deptId"></id>
        <result column="dept_name" property="deptName"></result>
      <!--property:Dept的属性名,column:传入的dept_id,select:查询的语句,fetchType有效值为 lazy 和 eager。 指定属性后,将在映射中忽略全局配置参数 lazyLoadingEnabled,使用属性的值-> <collection property="emp" column="dept_id" select="com.mybatis.mapper.EmpMapper.selectEmpsStep"/> </resultMap> <select id="selectDept" resultMap="myDept"> SELECT dept_id,dept_name FROM dept WHERE dept_id = #{dept_id} </select>

EmpMapper.xml:

 <select id="selectEmps" resultType="com.mybatis.bean.Emp">
        SELECT id,name,gender,email FROM emp WHERE dept_id = #{dept_id}
    </select>

mybatis全局配置:

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

最终实现分步查询和延迟加载,当我们访问只dept时,就不会去执行emp的SQL语句

        Dept dept = mapper.selectDept(10000);
        System.out.println(dept.getDeptName());
        System.out.println(dept.getEmp());        

当我们去访问emp时,就会执行emp的SQL语句。

不过官方说分步查询和延迟加载会有性能问题

 

 



 

posted @ 2020-04-20 15:21  来一杯可乐  阅读(465)  评论(0编辑  收藏  举报