MyBatis之resultMap介绍

一、resultMap简介

resultMap标签是为了映射select查询出来结果的集合,其主要作用是将实体类中的字段与数据库表中的字段进行关联映射。一句换,要解决属性名和字段名不一致的问题。

1.1 sql查询结果为null值:

  • 数据库的字段名:
id int(10),
 name varchar(20),
 pwd varchar(20)
  • Java中的实体类设计:
public class User {
     private int id;  //id
     private String name;   //姓名
     private String password;   //密码和数据库不一样!
 }
  • 接口定义:
//根据id查询用户
 User selectUserById(int id);
  • mapper映射:
<select id="selectUserById" resultType="user">
     select * from user where id = #{id}
 </select>
  • 程序测试:
@Test
 public void testSelectUserById() {
     SqlSession session = MybatisUtils.getSession();  //获取SqlSession连接
     UserMapper mapper = session.getMapper(UserMapper.class);
     User user = mapper.selectUserById(11);
     System.out.println(user);
     session.close();
 }
  • 结果输出:
User{id=11, name='zhangsan', password='null'}

结果中的密码为空,说明程序未关联到数据库中的pwd字段。

1.2 通过resultMap来解决

【自动映射】:mybatis会根据这些查询的列名(会将列名转化为小写,数据库不区分大小写) , 去对应的实体类中查找相应列名的set方法设值 , 由于找不到setPwd() , 所以password返回null 。

方法一:为列名指定别名 , 别名和java实体类的属性名一致 。

注意,这方法是将数据库中不匹配的字段取个别名,使其匹配java实体类中的属性名。

<select id="selectUserById" resultType="User">
     select id , name , pwd as password from user where id = #{id}
 </select>

方法二:使用ResultMap对结果集映射

<resultMap id="Map" type="User">
     <!-- id为主键 -->
     <id column="id" property="id"/>
     <!-- column是数据库表的列名 , property是对应实体类的属性名 -->
     <result column="name" property="name"/>
     <result column="pwd" property="password"/>
 </resultMap>
 <select id="selectUserById" resultMap="Map">
     select id , name , pwd  from user where id = #{id}
 </select>

这方法手动地将Java实体类地属性与数据库中地字段一一对应起来,这样就能解决字段名不匹配问题了,推荐使用。

二、resultMap

resultMap 元素是 MyBatis 中最重要最强大的元素,在为一些比如连接的复杂语句编写映射代码的时候,一份 result Map 能够代替实现同等功能的长达数千行的代码,resultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。

2.1 自动映射:

未显式指定resultMap的简单映射语句示例:

<select id="selectUserById" resultType="map">
     select id , name , pwd from user where id = #{id}
 </select>

上述语句只是简单地将所有的列映射到 Hash Map 的键上,这是因为 resultType的属性是“map”。但是 HashMap 不是一个很好的模型。需要考虑使用 JavaBean 或 POJO(Plain Old Java Objects,普通老式 Java 对象)作为模型的情形。

2.2 手动映射:

显示指定resultMap的映射语句示例:

<select id="selectUserById" resultMap="Map">
     select id , name , pwd from user where id = #{id}
 </select>

编写resultMap,实现手动映射:

<resultMap id="Map" type="User">
     <!-- id为主键 -->
     <id column="id" property="id"/>
     <!-- column是数据库表的列名 , property是对应实体类的属性名 -->
     <result column="name" property="name"/>
     <result column="pwd" property="password"/>
 </resultMap>

在操作数据库中,经常存在一对多,多对一的情况,这是会使用到一些高级的结果集映射,如 association,collection等。

三、总结:

  • 当实体类中的字段与数据库表中的字段相同时,可以将resultMap标签中的关联关系忽略。
  • 当实体类中的字段与数据库表中的字段不相同时,就需要在resultMap标签中将实体类字段与数据库字段一 一进行关联映射,或者开启驼峰规则,让它自动转换。
  • 如果mybatis配置文件中开启了驼峰设置后,数据库中的字段如果带下划线,那么就会去掉下划线,然后采用java驼峰规则。
  • 当进行单表简单查询时且返回值类型是基本类型时,一般mapper的返回类型尽量使用resultType=”xxxx”。
  • 当进行多表关联查询时,或者说xml中定义了相关的resultMap标签,那么就一般尽量使用resultMap=”xxxx”。
  • 在mapper.xml当中,resultType和resultMap是不能同时使用。
  • 关于数据库字段和实体类名称不相同的时候,要么采用resultMap标签, 要么启用驼峰规则,但是两者不能同时使用。