Mybatis select resultMap 详解

首先来介绍 select 元素

id
它和 Mapper 的命名空间组合起来是唯一的,提供给 MyBatis 调用。
如果命名空间和 id 组合起来不唯一,会抛出异常。

parameterType
传入参数的类型;可以给出类全名,也可以给出类别名,使用别名必须是 MyBatis 内部定义或自定义的;
基本数据类型:int , String , long , date(不知是 sql.date 还是 util.date);
复杂数据类型:类 和 Map;
可以选择 JavaBean,Map 等复杂的参数类型传递给 SQL。

resultType
从这条语句中返回的期望类型的类的完全限定名或别名。
注意如果是集合情形,那应该是集合可以包含的类型,而不能是集合本身。
使用 resultType 或 resultMap,但不能同时使用
定义类的全路径,在允许自动匹配的情况下,结果集将通过 JavaBean 的规范映射;
或者定义为 int,double,float 等参数...
也可以使用别名,但是要符合别名规范,不能和 resultMap 同时使用。
它是我们常用的参数之一,比如我们总计总条数
就可以把它的值设为 int。

resultMap
外部 resultMap 的命名引用。使用 resultMap 或 resultType,但不能同时使用;
它是映射集的引用,将执行强大的映射功能,我们可以使用 resultType 或者 resultMap 其中的一个,resultMap 可以给予我们自定义映射规则的机会
它是 MyBatis 最复杂的元素,可以配置映射规则,级联,typeHandler等

flushCache
它的作用是在调用 SQL 后,是否要求 MyBatis 清空之前查询的本地缓存和二级缓存

true/false,默认为false

useCache
启动二级缓存开关,是否要求 MyBatis 将此次结果缓存

true/false,默认为true

timeout
设置超时时间,超时之后抛出异常,秒
默认值为数据库厂商提供的 JDBC 驱动所设置的秒数

fetchSize
获取记录的总条数设定
默认值是数据库厂商提供的 JDBC 驱动所设的条数

示例:
xml 配置文件中

<select id="selectByPrimaryKey" resultMap="BaseResultMap"
        parameterType="java.lang.Integer">
        select
        <include refid="Base_Column_List" />
        from e_user
        where id = #{id,jdbcType=INTEGER}
    </select>

mapper 接口响应方法:

EUser selectByPrimaryKey(Integer id);

测试代码:

@Test
    // 测试自动映射
    public void testAutoMapping() throws IOException {
        // 2.获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 3.获取对应mapper
        EUserMapper mapper = sqlSession.getMapper(EUserMapper.class);
        // 4.执行查询语句并返回结果
        EUser user = mapper.selectByPrimaryKey(1);
        System.out.println(user);
    }

这里多说一点,传递多个参数时候需要注意的,请先看示例:

以下传递多个参数的时候,三种不同的方式。
一个是 map 传递参数,一个是注解直接传递参数,一个是用应用 java bean 传递。

<select id="selectByEmailAndSex1" resultMap="BaseResultMap"
        parameterType="map">
        select
        <include refid="Base_Column_List" />
        from t_user a
        where a.email like CONCAT('%', #{email}, '%') and
        a.sex =
        #{sex}
    </select>

    <select id="selectByEmailAndSex2" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from t_user a
        where a.email like CONCAT('%', #{email}, '%') and
        a.sex =
        #{sex}
    </select>

    <select id="selectByEmailAndSex3" resultMap="BaseResultMap"
        parameterType="com.enjoylearning.mybatis.entity.EmailSexBean">
        select
        <include refid="Base_Column_List" />
        from t_user a
        where a.email like CONCAT('%', #{email}, '%') and
        a.sex =
        #{sex}
    </select>

mapper java 代码和测试代码:

List<TUser> selectByEmailAndSex1(Map<String, Object> param);
    
List<TUser> selectByEmailAndSex2(@Param("email")String email,@Param("sex")Byte sex);
    
List<TUser> selectByEmailAndSex3(EmailSexBean esb);


// 多参数查询
@Test
public void testManyParamQuery() {
    // 2.获取sqlSession
    SqlSession sqlSession = sqlSessionFactory.openSession();
    // 3.获取对应mapper
    EUserMapper mapper = sqlSession.getMapper(EUserMapper.class);

    String email = "qq.com";
    Byte sex = 1;

    // 第一种方式使用map
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("email", email);
    params.put("sex", sex);
    List<EUser> list1 = mapper.selectByEmailAndSex1(params);
    System.out.println(list1.size());

    // 第二种方式直接使用参数
    List<EUser> list2 = mapper.selectByEmailAndSex2(email, sex);
    System.out.println(list2.size());

    // 第三种方式用对象
    EmailSexBean esb = new EmailSexBean();
    esb.setEmail(email);
    esb.setSex(sex);
    List<EUser> list3 = mapper.selectByEmailAndSex3(esb);
    System.out.println(list3.size());
    }

三种方式比较:
使用map传递参数;可读性差,导致可维护性和可扩展性差,杜绝使用;
使用注解传递参数;直观明了,当参数较少一般小于5个的时候,建议使用;
使用Java Bean的方式传递参数;当参数大于5个的时候,建议使用;

resultMap 元素 属性

resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,在对复杂语句进行联合映射的时候,它很可能可以代替数千行的同等功能的代码。

ResultMap 的设计思想是,简单的语句不需要明确的结果映射,而复杂一点的语句只需要描述它们的关系就行了。

id
当前命名空间中的一个唯一标识,用于标识一个 result map.

type
类的完全限定名, 或者一个类型别名 (内置的别名可以参考上面的表格).

autoMapping
如果设置这个属性,MyBatis 将会为这个 ResultMap 开启或者关闭自动映射。这个属性会覆盖全局的属性
autoMappingBehavior。默认值为:unset。

<resultMap id="BaseResultMap" type="EUser">
        <!-- <constructor> <idArg column="id" javaType="int"/> <arg column="user_name" 
            javaType="String"/> </constructor> -->
        <id column="id" property="id" />
        <result column="user_name" property="userName" />
        <result column="real_name" property="realName" />
        <result column="sex" property="sex" />
        <result column="mobile" property="mobile" />
        <result column="email" property="email" />
        <result column="note" property="note" />
    </resultMap>

resultMap 元素 子元素

constructor 用于在实例化类时,注入结果到构造方法中。
-idArg ID 参数;标记出作为 ID 的结果可以帮助提高整体性能。
-arg 将被注入到构造方法的一个普通结果。

id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能
result – 注入到字段或 JavaBean 属性的普通结果

association – 一个复杂类型的关联;许多结果将包装成这种类型
嵌套结果映射 – 关联可以指定为一个 resultMap 元素,或者引用一个

collection – 一个复杂类型的集合
•嵌套结果映射 – 集合可以指定为一个 resultMap 元素,或者引用一个

discriminator – 使用结果值来决定使用哪个 resultMap
-case – 基于某些值的结果映射
嵌套结果映射 一个 case 也是一个映射它本身的结果,因此可以包含很多相 同的元素,或者它可以参照一个外部的 resultMap

id & result

id 和 result 都将一个列的值映射到一个简单数据类型(字符串,整型,双精度浮点数,日期等)的属性或字段。
两者之间的唯一不同是, id 表示的结果将是对象的标识属性,这会在比较对象实例时用到。 这样可以提高整体的性能,尤其是缓存和嵌套结果映射(也就是联合映射)的时候。

property
POJO 中映射到列结果的字段或者属性。如果 POJO 的属性匹配的是存在的,和给定 SQL 列名(column 元素)相同的,那么 MyBatis 就会自动映射;

column
SQL 中的列名,或者是列的别名。一般情况下,这和 传递给 resultSet.getString(columnName) 方法的参数一样。

javaType
配置的 Java 的类;

jdbcType
配置的数据库的类型;

typeHandler
类型处理器,使用这个属性,你可以覆盖默 认的类型处理器。这个属性值是一个类型处理 器实现类的完全限定名,或者是类型别名。

constructor

一个pojo不存在没有参数的构造方法,就需要使用 constructor。
为了通过名称来引用构造方法参数,你可以添加 @Param 注解,指定参数名称的前提下,以任意顺序编写 arg 元素。

欢迎大家关注,vx公众号同名

推荐阅读更多精彩内容