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标签, 要么启用驼峰规则,但是两者不能同时使用。