Mybatis resultMap复杂查询结果映射

结果映射resultMap

<!-- 官网示例,大多数情况下我们的resultMap没有这么复杂 -->
<resultMap id="detailedBlogResultMap" type="Blog">
  <constructor>
    <idArg column="blog_id" javaType="int"/>
  </constructor>
  <result property="title" column="blog_title"/>
  <association property="author" javaType="Author">
    <id property="id" column="author_id"/>
    <result property="username" column="author_username"/>
    <result property="password" column="author_password"/>
    <result property="email" column="author_email"/>
    <result property="bio" column="author_bio"/>
    <result property="favouriteSection" column="author_favourite_section"/>
  </association>
  <collection property="posts" ofType="Post">
    <id property="id" column="post_id"/>
    <result property="subject" column="post_subject"/>
    <association property="author" javaType="Author"/>
    <collection property="comments" ofType="Comment">
      <id property="id" column="comment_id"/>
    </collection>
    <collection property="tags" ofType="Tag" >
      <id property="id" column="tag_id"/>
    </collection>
    <discriminator javaType="int" column="draft">
      <case value="1" resultType="DraftPost"/>
    </discriminator>
  </collection>
</resultMap>
  • constructor - 用于在实例化类时,注入结果到构造方法中
    • idArg - ID 参数;标记出作为 ID 的结果可以帮助提高整体性能
    • arg - 将被注入到构造方法的一个普通结果
  • id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能
  • result – 注入到字段或 JavaBean 属性的普通结果
  • association – 一个复杂类型的关联;许多结果将包装成这种类型(嵌套结果映射:关联 resultMap 元素,或是对其它结果映射的引用)
  • collection – 一个复杂类型的集合(嵌套结果映射:集合可以是 resultMap 元素,或是对其它结果映射的引用)
  • discriminator – 使用结果值来决定使用哪个 resultMap
    • case – 基于某些值的结果映射(嵌套结果映射:case 也是一个结果映射,因此具有相同的结构和元素;或者引用其它的结果映射)

resultMap 标签属性

属性说明
id当前命名空间中的一个唯一标识,用于标识一个结果映射。
type类的完全限定名, 或者一个类型别名(关于内置的类型别名,可以参考上面的表格)。
autoMapping如果设置这个属性,MyBatis 将会为本结果映射开启或者关闭自动映射。 这个属性会覆盖全局的属性 autoMappingBehavior。默认值:未设置(unset)。

id和result子标签

属性说明
property映射到列结果的字段或属性。如果 JavaBean 有这个名字的属性(property),会先使用该属性。否则 MyBatis 将会寻找给定名称的字段(field)。 无论是哪一种情形,你都可以使用常见的点式分隔形式进行复杂属性导航。 比如,你可以这样映射一些简单的东西:“username”,或者映射到一些复杂的东西上:“address.street.number”。
column数据库中的列名,或者是列的别名。一般情况下,这和传递给 resultSet.getString(columnName) 方法的参数一样。
javaType一个 Java 类的全限定名,或一个类型别名(关于内置的类型别名,可以参考上面的表格)。 如果你映射到一个 JavaBean,MyBatis 通常可以推断类型。然而,如果你映射到的是 HashMap,那么你应该明确地指定 javaType 来保证行为与期望的相一致。
jdbcTypeJDBC 类型,所支持的 JDBC 类型参见这个表格之后的“支持的 JDBC 类型”。 只需要在可能执行插入、更新和删除的且允许空值的列上指定 JDBC 类型。这是 JDBC 的要求而非 MyBatis 的要求。如果你直接面向 JDBC 编程,你需要对可以为空值的列指定这个类型。
typeHandler我们在前面讨论过默认的类型处理器。使用这个属性,你可以覆盖默认的类型处理器。 这个属性值是一个类型处理器实现类的全限定名,或者是类型别名。

我们常用的也就property和column而已。

    <resultMap id="id" type="emp">
        <id property="empno" column="empno"></id>
        <result property="ename" column="ename"></result>
        ...此处省略其他属性的配置
    </resultMap>

id标签和result标签的区别

id 元素对应的属性会被标记为对象的标识符,在比较对象实例时使用。 这样可以提高整体的性能,尤其是进行缓存和嵌套结果映射(也就是连接映射)的时候。(所以主键列我们应使用id标签)

constructor子标签

constructor子标签和我们的id、result标签差不多。项目中使用的相对较少,此处不做讲解。

association 关联

比如我们现在要查询emp每个员工以及他们对应的部门,如果我们的Emp对象内部嵌套一个Dept对象属性,我们用association 关联查询来达到这个效果。由于我们已经有了emp对象,所以我们重新定义一个Emp1来表示我们的结果对象

Emp1

@Data
public class Emp1 {
    /**id*/
    private Long empno;
    /**姓名*/
    private String ename;
    /**岗位*/
    private String job;
    /**直接上级id*/
    private Long mgr;
    /**受雇时间*/
    private Date hirdate;
    /**基本工资*/
    private Double sal;
    /**奖金*/
    private Double comm;
    /**部门编号*/
    private Long deptno;
    /**Emp内部嵌套的dept对象*/
    private Dept dept;
}

Dept

@Data
public class Dept {
    private String deptno;
    private String dname;
    private String loc;
}

xml映射文件

<resultMap id="emp1" type="emp1">
        <id column="empno" property="empno"/>
        <result column="ename" property="ename"/>
        <result column="job" property="job"/>
        <result column="mgr" property="mgr"/>
        <result column="hirdate" property="hirdate"/>
        <result column="sal" property="sal"/>
        <result column="comm" property="comm"/>
        <result column="deptno" property="deptno"/>
        <!--
         property:emp对象中的dept属性
         column:数据库字段名称,一般是关联字段
         javaType:对应的java对象(注意此处我们别名了)
         -->
        <association property="dept" column="deptno" javaType="Dept">
            <id column="deptno" property="deptno"/>
            <result column="dname" property="dname"/>
            <result column="loc" property="loc"/>
        </association>
    </resultMap>
    <select id="selectEmp1" resultMap="emp1">
        select * from emp,dept where emp.deptno = dept.deptno
    </select>

执行结果如下

[Emp1(empno=7782, ename=CLARK, job=MANAGER, mgr=7839, hirdate=null, sal=2450.0, comm=null, deptno=10, dept=Dept(deptno=10, dname=ACCOUNTING, loc=NEW YORK)), ......

association也可以直接引用其他的resultMap

    <resultMap id="emp1" type="Emp1">
        <id column="empno" property="empno"/>
        <result column="ename" property="ename"/>
        <result column="job" property="job"/>
        <result column="mgr" property="mgr"/>
        <result column="hirdate" property="hirdate"/>
        <result column="sal" property="sal"/>
        <result column="comm" property="comm"/>
        <result column="deptno" property="deptno"/>
        <association property="dept" column="deptno" javaType="Dept" resultMap="dept"/>
    </resultMap>
    <resultMap id="dept" type="Dept">
        <id column="deptno" property="deptno"/>
        <result column="dname" property="dname"/>
        <result column="loc" property="loc"/>
    </resultMap>
    <select id="selectEmp1" resultMap="emp1">
        select * from emp,dept where emp.deptno = dept.deptno
    </select>

使用association的columnPrefix属性可以对查询结果列添加名称前缀通常在关联表中有相同字段时添加,用以区分不同的resultSet结果集。

集合查询

比如我们要查询所有的部门,以及部门下所有的员工的信息

xml配置如下

   <resultMap id="dept1" type="Dept1">
        <id column="deptno" property="deptno"/>
        <result column="dname" property="dname"/>
        <result column="loc" property="loc"/>
        <!-- collection也可以使用resultMap属性来引用其他的结果集映射 -->
        <collection property="empList" ofType="Emp">
            <id column="empno" property="empno"/>
            <result column="ename" property="ename"/>
            <result column="job" property="job"/>
            <result column="mgr" property="mgr"/>
            <result column="hirdate" property="hirdate"/>
            <result column="sal" property="sal"/>
            <result column="comm" property="comm"/>
            <result column="deptno" property="deptno"/>
        </collection>
    </resultMap>
    <select id="selectDept1" resultMap="dept1">
        select * from emp,dept where emp.deptno = dept.deptno
    </select>

注意:JavaBean中两个的引用属性最好不要嵌套相互引用了。

跨xml映射文件引用resultMap

比如我们目前在a.xml中定义了一个id为a的resultMap,现在我们在b.xml映射文件中要使用该resultMap,我们可以如下使用:

<select id="selectDept1" resultMap="com.yyoo.mybatis.mapper.EmpMapper.a">
    select * from emp,dept where emp.deptno = dept.deptno
</select>

com.yyoo.mybatis.mapper.EmpMapper为a.xml映射文件的namespace属性值,一般就是对应的Mapper接口的全路径地址,"a"就是对应的resultMap的id值。

上一篇:Mybatis select查询
下一篇:Mybatis 批量插入

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值