Mybatis开发要点-resultType和resultMap的区别?

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Mybatis开发要点-resultType和resultMap的区别?

Mybatis返回Xml返回值有resultType和resultMap,我们一般都该如何选择呢?


一、resultType


1、resultType介绍


当使用resultType做SQL语句返回结果类型处理时,对于SQL语句查询出的字段在相应的pojo中必须有和它相同的字段对应,而resultType中的内容就是pojo在本项目中的位置。


2、映射规则


  1. 基本类型  :resultType=基本类型  List类型:   resultType=List中元素的类型
  2. Map类型    单条记录:resultType =map    多条记录:resultType =Map中value的类型


3、自动映射注意事项


  1. 前提:SQL列名和JavaBean的属性是一致的;
  2. 使用resultType,如用简写需要配置typeAliases (别名);
  3. 如果列名和JavaBean不一致,但列名符合单词下划线分割,Java是驼峰命名法,则mapUnderscoreToCamelCase可设置为true;


4、代码演示

1、t_user_test.sql准备

CREATE TABLE `t_user_test` (
  `id` int(20) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(60) DEFAULT NULL COMMENT '用户名称',
  `real_name` varchar(60) DEFAULT NULL COMMENT '真实名称',
  `sex` tinyint(3) DEFAULT NULL COMMENT '姓名',
  `mobile` varchar(20) DEFAULT NULL COMMENT '电话',
  `email` varchar(60) DEFAULT NULL COMMENT '邮箱',
  `note` varchar(200) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=142 DEFAULT CHARSET=utf8;


2、实体类

package com.enjoylearning.mybatis.entity;
import java.io.Serializable;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.mysql.jdbc.Blob;
public class TUser implements Serializable{
    private Integer id;
    private String userName;
    private String realName;
    private Byte sex;
    private String mobile;
    private String email;
    private String note;
    private TPosition position;
    private List<TJobHistory> jobs ;
    private List<HealthReport> healthReports;
    private List<TRole> roles;
  @Override
  public String toString() {
    String positionId=  (position == null ? "" : String.valueOf(position.getId()));
    return "TUser [id=" + id + ", userName=" + userName + ", realName="
        + realName + ", sex=" + sex + ", mobile=" + mobile + ", email="
        + email + ", note=" + note + ", positionId=" + positionId + "]";
  }
  public Integer getId() {
    return id;
  }
  public void setId(Integer id) {
    this.id = id;
  }
  public String getUserName() {
    return userName;
  }
  public void setUserName(String userName) {
    this.userName = userName;
  }
  public String getRealName() {
    return realName;
  }
  public void setRealName(String realName) {
    this.realName = realName;
  }
  public Byte getSex() {
    return sex;
  }
  public void setSex(Byte sex) {
    this.sex = sex;
  }
  public String getMobile() {
    return mobile;
  }
  public void setMobile(String mobile) {
    this.mobile = mobile;
  }
  public String getEmail() {
    return email;
  }
  public void setEmail(String email) {
    this.email = email;
  }
  public String getNote() {
    return note;
  }
  public void setNote(String note) {
    this.note = note;
  }
  public TPosition getPosition() {
    return position;
  }
  public void setPosition(TPosition position) {
    this.position = position;
  }
  public List<TJobHistory> getJobs() {
    return jobs;
  }
  public void setJobs(List<TJobHistory> jobs) {
    this.jobs = jobs;
  }
  public List<HealthReport> getHealthReports() {
    return healthReports;
  }
  public void setHealthReports(List<HealthReport> healthReports) {
    this.healthReports = healthReports;
  }
  public List<TRole> getRoles() {
    return roles;
  }
  public void setRoles(List<TRole> roles) {
    this.roles = roles;
  }
}

3、Mapper接口类

public interface TUserTestMapper {
  TUser selectByPrimaryKey(Integer id);
  List<TUser> selectAll();
}


4、Mapper 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.mybatis.mapper.TUserTestMapper">
  <select id="selectByPrimaryKey" resultType="TUser">
    select
    id, user_name, real_name, sex, mobile, email, note
    from t_user_test
    where id = #{id,jdbcType=INTEGER}
  </select>
  <select id="selectAll" resultType="TUser">
    select
    id, user_name, real_name, sex, mobile, email, note
    from t_user_test
  </select>
</mapper>


5、配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <properties resource="db.properties"/>
  <settings>
    <!-- 设置自动驼峰转换    -->
    <setting name="mapUnderscoreToCamelCase" value="true" />
    <!-- 开启懒加载 -->    
     <!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。默认:true -->
    <setting name="aggressiveLazyLoading" value="false" />
  </settings>
  <!-- 别名定义 -->
  <typeAliases>
    <package name="com.enjoylearning.mybatis.entity" />
  </typeAliases>
  <plugins>
    <plugin interceptor="com.enjoylearning.mybatis.Interceptors.ThresholdInterceptor"> 
      <property name="threshold" value="10"/>
    </plugin>
       <plugin interceptor="com.github.pagehelper.PageInterceptor">
      <property name="pageSizeZero" value="true" />
    </plugin>
  </plugins>
  <!--配置environment环境 -->
  <environments default="development">
    <!-- 环境配置1,每个SqlSessionFactory对应一个环境 -->
    <environment id="development">
      <transactionManager type="JDBC" />
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://ip:port/test?useUnicode=true" />
        <property name="username" value="root" />
        <property name="password" value="123456" />
      </dataSource>
    </environment>
  </environments>
  <!-- 映射文件,mapper的配置文件 -->
  <mappers>
    <!--直接映射到相应的mapper文件 -->
    <mapper resource="sqlmapper/TUserTestMapper.xml" />
  </mappers>
</configuration>  


6、启动测试类

public class MybatisDemo2 {
  private SqlSessionFactory sqlSessionFactory;
  @Before
  public void init() throws IOException {
    //--------------------第一阶段---------------------------
      // 1.读取mybatis配置文件创SqlSessionFactory
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    // 1.读取mybatis配置文件创SqlSessionFactory
    sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    inputStream.close();
  }
  @Test
  //知识点:resultType
  public void testAutoMapping() throws IOException {
    // 2.获取sqlSession 
    SqlSession sqlSession = sqlSessionFactory.openSession();
    // 3.获取对应mapper
    TUserTestMapper mapper = sqlSession.getMapper(TUserTestMapper.class);
    // 4.执行查询语句并返回多条数据
    List<TUser> users = mapper.selectAll();
    for (TUser tUser : users) {
      System.out.println(tUser);
    }
  }
}


7、执行结果

sql语句:“com.mysql.jdbc.JDBC4PreparedStatement@654f0d9c: select
    id, user_name, real_name, sex, mobile, email, note
    from t_user_test”执行时间为:35毫秒,已经超过阈值!
TUser [id=1, userName=zhangsan, realName=张三, sex=1, mobile=186995587411, email=zhangsan@qq.com, note=zhangsan的备注, positionId=]
TUser [id=2, userName=lisi, realName=李四, sex=1, mobile=18677885200, email=lisi@qq.com, note=lisi的备注, positionId=]
TUser [id=3, userName=wangwu, realName=王五, sex=2, mobile=18695988747, email=xxoo@163.com, note=wangwu's note, positionId=]


resultType当返基本类型的时候建议选择,当返回POJO类的时候由于需要完全和数据库字段进行对应,存在不灵活、问题排查难等问题。


二、resultMap


1、resultMap  介绍


resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,在对复杂语句进行联合映射的时候,它很可能可以代替数千行的同等功能的代码。ResultMap 的设计思想是,简单的语句不需要明确的结果映射,而复杂一点的语句只需要描述它们的关系就行了。


2、resultMap属性


属性

描述

id

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

type

类的完全限定名, 或者一个类型别名.

autoMapping

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


3、使用场景

  1. 字段有自定义的转化规则
  2. 复杂的多表查询

4、resultMap子元素属性

  1. id –一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能,一对多的查询中用于结果集合并;
  2. result – 注入到字段或 JavaBean 属性的普通结果
  3. association – 一个复杂类型的关联;许多结果将包装成这种类型。关联可以指定为一个
  1. resultMap 元素,或者引用一个
  2. collection – 一个复杂类型的集合

5、代码演示

实体类,配置文件同上

1、mapper接口


public interface TUserMapper {
  List<TUser> selectTestResultMap();
}

2、Mapper.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.mybatis.mapper.TUserMapper">
  <resultMap id="UserResultMap" type="TUser" autoMapping="true">
    <id column="id" property="id" />
        <result column="userName" property="userName"/>
    <result column="realName" property="realName" />
    <result column="sex" property="sex" />
    <result column="mobile" property="mobile" />
    <result column="email" property="email" />
    <result column="note" property="note" />
    <association property="position" javaType="TPosition" columnPrefix="post_">
      <id column="id" property="id"/>
      <result column="name" property="postName"/>
      <result column="note" property="note"/>
    </association>
  </resultMap>
  <select  id="selectTestResultMap" resultMap="UserResultMap" >
    select
        a.id,
        userName,
      realName,
      sex,
      mobile,
      email,
      a.note,
      b.id  post_id,
      b.post_name,
      b.note post_note
    from t_user a,
      t_position b
    where a.position_id = b.id
  </select>
</mapper>


3、启动测试

public class MybatisDemo2 {
  private SqlSessionFactory sqlSessionFactory;
  @Before
  public void init() throws IOException {
    //--------------------第一阶段---------------------------
      // 1.读取mybatis配置文件创SqlSessionFactory
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    // 1.读取mybatis配置文件创SqlSessionFactory
    sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    inputStream.close();
  }
  @Test
  public void testResultMap() throws IOException {
    //--------------------第二阶段---------------------------
    // 2.获取sqlSession 
    SqlSession sqlSession = sqlSessionFactory.openSession();
    // 3.获取对应mapper
    TUserMapper mapper = sqlSession.getMapper(TUserMapper.class);
    //--------------------第三阶段---------------------------
    // 4.执行查询语句并返回单条数据
    List<TUser> users = mapper.selectTestResultMap();
    for (TUser tUser : users) {
      System.out.println(tUser.getUserName());
      System.out.println(tUser.getPosition().getPostName());
    }
  }
}


4、执行结果

sql语句:“com.mysql.jdbc.JDBC4PreparedStatement@19bb07ed: select
        a.id,
        userName,
      realName,
      sex,
      mobile,
      email,
      a.note,
      b.id  post_id,
      b.post_name,
      b.note post_note
    from t_user a,
      t_position b
    where a.position_id = b.id”执行时间为:52毫秒,已经超过阈值!
zhangsan
总经理
lisi
零时工
wangwu
总经理



三、结论


当返回对象为基础类型时建议走resultType,当返回对象为POJO时,强制走resultMap。同时可以参考阿里巴巴JAVA开发手册中的5.4.3节,返回要解耦,不讷讷更直接使用resultClass。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
19天前
|
SQL 安全 Java
MyBatis(6)#{}和${}的区别
在MyBatis中,`#{}`和`${}`是用于在SQL语句中嵌入参数的两种方式。`#{}`用于预处理参数,可以防止SQL注入;而`${}`进行直接字符串替换,适用于动态插入表名或列名,但存在SQL注入风险。建议优先使用`#{}`,并在必要时谨慎使用`${}`。
|
2月前
|
SQL XML Java
mybatis复习02,简单的增删改查,@Param注解多个参数,resultType与resultMap的区别,#{}预编译参数
文章介绍了MyBatis的简单增删改查操作,包括创建数据表、实体类、配置文件、Mapper接口及其XML文件,并解释了`#{}`预编译参数和`@Param`注解的使用。同时,还涵盖了resultType与resultMap的区别,并提供了完整的代码实例和测试用例。
mybatis复习02,简单的增删改查,@Param注解多个参数,resultType与resultMap的区别,#{}预编译参数
|
1月前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
45 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
2月前
|
Java 数据库连接 数据格式
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
IOC/DI配置管理DruidDataSource和properties、核心容器的创建、获取bean的方式、spring注解开发、注解开发管理第三方bean、Spring整合Mybatis和Junit
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
|
3月前
|
SQL Java 数据库连接
Spring Boot联手MyBatis,打造开发利器:从入门到精通,实战教程带你飞越编程高峰!
【8月更文挑战第29天】Spring Boot与MyBatis分别是Java快速开发和持久层框架的优秀代表。本文通过整合Spring Boot与MyBatis,展示了如何在项目中添加相关依赖、配置数据源及MyBatis,并通过实战示例介绍了实体类、Mapper接口及Controller的创建过程。通过本文,你将学会如何利用这两款工具提高开发效率,实现数据的增删查改等复杂操作,为实际项目开发提供有力支持。
177 0
|
3月前
|
SQL Java 数据库连接
MyBatis 和 Hibernate 有什么区别?
【8月更文挑战第21天】
65 0
|
3月前
|
SQL Java 数据库连接
后端框架的学习----mybatis框架(7、使用注解开发)
这篇文章讲述了如何使用MyBatis框架的注解方式进行开发,包括在接口上使用注解定义SQL语句,并通过动态代理实现对数据库的增删改查操作,同时强调了接口需要在核心配置文件中注册绑定。
|
3月前
|
SQL Java 数据库连接
在mybatis中#{}和${}的区别
在MyBatis中,使用#{}可以防止SQL注入,它通过预处理语句来安全地设置参数值,而${}会将传入的数据直接插入SQL语句中,不安全,通常用于传入数据库对象或在确保数据安全的情况下使用。
|
4月前
|
Java 数据库连接 mybatis
SpringBoot配置Mybatis注意事项,mappers层下的name命名空间,要落实到Dao的video类,resultType要落到bean,配置好mybatis的对应依赖。
SpringBoot配置Mybatis注意事项,mappers层下的name命名空间,要落实到Dao的video类,resultType要落到bean,配置好mybatis的对应依赖。
|
5月前
|
SQL Java 数据库连接
Mybatis如何使用mapper代理开发
Mybatis如何使用mapper代理开发