10、mybatis-映射文件-resultMap

2019-08-18  本文已影响0人  唯老

一、概要

resultMap 结果映射集,是MyBatis 中最重要最强大也是最复杂的元素,主要用来定义映射规则、级联操作以及定义类型转化器等。

二、resultMap结构

元素的完整结构

<!--
      1. type 对应的返回类型,可以是javabean, 也可以是其它
      2. id 必须唯一, 用于标示这个resultMap的唯一性,在使用resultMap的时候,就是通过id引用
      3. extends 继承其他resultMap标签
     -->
<resultMap id="唯一的标识" type="映射的pojo对象">
  <!--
            1. id 主键,配合select标签的 resultMap属性使用
            2. property 属性对应javabean的属性名
            3. column 对应数据库表的列名
   -->
  <id column="表的主键字段,或者可以为查询语句中的别名字段"
      jdbcType="字段类型"
      property="映射pojo对象的主键属性"/>
  <!--
        result 与id相比,对应普通属性
  -->
  <result column="表的一个字段(可以为任意表的一个字段)"
          jdbcType="字段类型"
          property="映射到pojo对象的一个属性(须为type定义的pojo对象中的一个属性)"/>
  <!--
     constructor 对应javabean中的构造方法
   -->
  <constructor>
    <!-- idArg 对应构造方法中的id参数 -->
    <idArg column="构造方法id"/>
    <!-- arg 对应构造方法中的普通参数 -->
    <arg column="构造方法普通属性"/>
  </constructor>
  <!--
    association 为关联关系,是实现一对一的关键
    1. property 为javabean中容器对应字段名
    2. javaType 指定关联的类型,当使用select属性时,无需指定关联的类型
    3. select 使用另一个select查询封装的结果
    4. column 为数据库中的列名,对应的是主查询语句中的查询结果列,如果主查询语句中没有写as别名,那么就是数据库列名。如果写了别名,那么这里的column就要跟别名保持一致与select配合使用
    5.fetchType 可选的。有效值为 lazy和eager。 如果使用了,它将取代全局配置参数lazyLoadingEnabled。
  -->
  <association property="pojo的一个对象属性" javaType="pojo关联的pojo对象">
    <!--
     使用select属性时,无需下面的配置
    -->
    <id column="关联pojo对象对应表的主键字段"
        jdbcType="字段类型"
        property="关联pojo对象的主席属性"/>
    <result column="任意表的字段"
            jdbcType="字段类型"
            property="关联pojo对象的属性"/>
  </association>
  <!--
    有时一个单独的数据库查询也许返回很多不同 (但是希望有些关联) 数据类型的结果集。
    鉴别器元素就是被设计来处理这个情况的, 还有包括类的继承层次结构。
    鉴别器非常容易理 解,因为它的表现很像 Java 语言中的 switch 语句。
    定义鉴别器指定了 column 和 javaType 属性。列是 MyBatis 查找比较值的地方。
    JavaType 是需要被用来保证等价测试的合适类型(尽管字符串在很多情形下都会有用)
  -->
  <discriminator javaType="value的类型">
    <case value="1" resultMap="引用外部resultMap"/>
    <case value="2" resultMap="引用外部resultType"/>
    ...
  </discriminator>
  <!--
    collection 为关联关系,是实现一对多的关键
    1. property 为javabean中容器对应字段名
    2. ofType 指定集合中元素的对象类型
    3. select 使用另一个查询封装的结果
    4. column 为数据库中的列名,对应的是主查询语句中的查询结果列,如果主查询语句中没有写as别名,那么就是数据库列名。如果写了别名,那么这里的column就要跟别名保持一致与select配合使用
    5.fetchType 可选的。有效值为 lazy和eager。 如果使用了,它将取代全局配置参数lazyLoadingEnabled。
   -->
  <!-- 集合中的property须为ofType定义的pojo对象的属性-->
  <collection property="pojo的集合属性"
              ofType="集合中的pojo对象">
    <!--
              使用select属性时,无需下面的配置
    -->
    <id column="集合中pojo对象对应的表的主键字段"
        jdbcType="字段类型"
        property="集合中pojo对象的主键属性"/>
    <result column="可以为任意表的字段"
            jdbcType="字段类型"
            property="集合中的pojo对象的属性"/>
  </collection>
</resultMap>

结构图

image

三、操作步骤

如果简单的业务一般不需要使用 resultMap 可以直接使用自动映射,使用 resultType 属性,但比如表的列名还类的属性名字不同的情况,有时候需要更为复杂的映射或级联,这时候就需要使用<select> 元素的 resultMap 属性配置映射集合

步骤1 SQL文件

CREATE TABLE IF NOT EXISTS goods(
    id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT "商品主键",
    shop_id SMALLINT UNSIGNED NOT NULL COMMENT "商铺id",
    cate_id SMALLINT UNSIGNED NOT NULL COMMENT "分类id",
    local_id SMALLINT UNSIGNED NOT NULL COMMENT "地区id",
    title   VARCHAR(30) NOT NULL DEFAULT "" COMMENT "商品主标题",
    sub_title VARCHAR(255) NOT NULL DEFAULT "" COMMENT "商品副标题",
    price DECIMAL(7,1) NOT NULL DEFAULT 0 COMMENT "商品价格",
    old_price DECIMAL(7,1) NOT NULL DEFAULT 0 COMMENT "原价",
    goods_img VARCHAR(60) NOT NULL COMMENT "商品图",
    INDEX idx_shop_id (shop_id),
    INDEX idx_cate_id (cate_id),
    INDEX idx_local_id (local_id),
)ENGINE=innodb DEFAULT CHARSET=utf8 COMMENT="商品表";

步骤2 创建 Bean 类

public class Goods {
    private Integer id;
    private Short shopId;
    private Short cateId;
    private Short localId;
    private String title;
    private String subTitle;
    private BigDecimal price;
    private BigDecimal oldPrice;
    private String goodsImg;
    ...省略其它
}

步骤3 创建接口

public interface GoodsMapper {
    Goods findById(@Param("id")Integer id);
}

步骤4 创建Mapper.xml文件配置resultMap

<?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.vip.mybatis.mapper.GoodsMapper">
  <resultMap id="BaseResultMap" type="com.vip.mybatis.entity.Goods">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="shop_id" jdbcType="SMALLINT" property="shopId" />
    <result column="cate_id" jdbcType="SMALLINT" property="cateId" />
    <result column="local_id" jdbcType="SMALLINT" property="localId" />
    <result column="title" jdbcType="VARCHAR" property="title" />
    <result column="sub_title" jdbcType="VARCHAR" property="subTitle" />
    <result column="price" jdbcType="DECIMAL" property="price" />
    <result column="old_price" jdbcType="DECIMAL" property="oldPrice" />
    <result column="goods_img" jdbcType="VARCHAR" property="goodsImg" />
  </resultMap>
  <sql id="base_column_list">
    id, shop_id, cate_id, loca_id, title, sub_title, price, old_price, goods_img
  </sql>
    <select id="findById"  resultMap="BaseResultMap">
    SELECT
    <include refid="base_column_list" />
    FROM goods
    WHERE id = #{id}
  </select>
</mapper>

四、映射文件小结

  1. 查询出来的结果集只有一行且一列,可以使用简单类型进行输出映射。
  2. 查询pojo对象和pojo集合
    不管是输出的pojo单个对象还是一个集合(list中包括pojo),在mapper.xml中resultType指定的类型是一样的。在mapper.java指定的方法返回值类型不一样:
    • 输出单个pojo对象,方法返回值是单个对象类型
    • 输出pojo对象list,方法返回值是List
  3. 输出pojo对象可以改用hashmap输出类型,将输出的字段名称作为map的key,value为字段值。如果是集合,那就是list里面套了HashMap
  4. 使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功
上一篇下一篇

猜你喜欢

热点阅读