<resultMap>元素
<resultMap>元素表示结果映射集,是MyBatis中最重要也是最强大的元素。它的主要作用是定义映射规则、级联的更新以及定义类型转化器等。
<resultMap>元素中包含了一些子元素,它的元素结构如下所示。
<!--resultMap的元素结构 -->
<resultMap type="" id="">
<constructor> <!-- 类在实例化时,用来注入结果到构造方法中-->
<idArg/> <!-- ID参数;标记结果作为ID-->
<arg/> <!-- 注入到构造方法的一个普通结果-->
</constructor>
<id/> <!-- 用于表示哪个列是主键-->
<result/> <!-- 注入到字段或JavaBean属性的普通结果-->
<association property="" /> <!-- 用于一对一关联 -->
<collection property="" /> <!-- 用于一对多关联 -->
<discriminator javaType=""> <!-- 使用结果值来决定使用哪个结果映射-->
<case value="" /> <!-- 基于某些值的结果映射 -->
</discriminator>
</resultMap>
<resultMap>元素的type属性表示需要映射的POJO,id属性是这个resultMap的唯一标识。它的子元素<constructor>用于配置构造方法(当一个POJO中未定义无参的构造方法时,就可以使用<constructor>元素进行配置)。子元素<id>用于表示哪个列是主键,而<result>用于表示POJO和数据表中普通列的映射关系。<association>和<collection>用于处理多表时的关联关系,而<discriminator>元素主要用于处理一个单独的数据库查询返回很多不同数据类型结果集的情况。
在默认情况下,MyBatis程序在运行时会自动的将查询到的数据与需要返回的对象的属性进行匹配赋值(需要表中的列名与对象的属性名称完全一致)。然而实际开发时,数据表中的列和需要返回的对象的属性可能不会完全一致,这种情况下MyBatis是不会自动赋值的。此时,就可以使用<resultMap>元素进行处理。
接下来,通过一个具体的案例来演示<resultMap>元素在此种情况的使用,具体步骤如下。
(1)在mybatis数据库中,创建一个t_user表,并插入几条测试数据。
USE mybatis;
CREATE TABLE t_user(
t_id INT PRIMARY KEY AUTO_INCREMENT,
t_name VARCHAR(50),
t_age INT
);
INSERT INTO t_user(t_name,t_age) VALUES('Lucy',25);
INSERT INTO t_user(t_name,t_age) VALUES('Lili',20);
INSERT INTO t_user(t_name,t_age) VALUES('Jim',20);
(2)在com.itheima.po包中,创建持久化类User,并在类中定义id、name和age属性,以及其getter/setter方法和toString()方法,如文件1所示。
文件1 User.java
1 package com.itheima.po;
2 public class User {
3 private Integer id;
4 private String name;
5 private Integer age;
6 public Integer getId() {
7 return id;
8 }
9 public void setId(Integer id) {
10 this.id = id;
11 }
12 public String getName() {
13 return name;
14 }
15 public void setName(String name) {
16 this.name = name;
17 }
18 public Integer getAge() {
19 return age;
20 }
21 public void setAge(Integer age) {
22 this.age = age;
23 }
24 @Override
25 public String toString() {
26 return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
27 }
28 }
(3)在com.itheima.mapper包下,创建映射文件UserMapper.xml,并在映射文件中编写映射查询语句,如文件2所示。
文件2 UserMapper.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE mapper
3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5 <mapper namespace="com.itheima.mapper.UserMapper">
6 <resultMap type="com.itheima.po.User" id="resultMap">
7 <id property="id" column="t_id"/>
8 <result property="name" column="t_name"/>
9 <result property="age" column="t_age"/>
10 </resultMap>
11 <select id="findAllUser" resultMap="resultMap">
12 select * from t_user
13 </select>
14 </mapper>
在文件2中,<resultMap>的子元素<id>和<result>的property属性表示User类的属性名,column属性表示数据表t_user的列名。<select>元素的resultMap属性表示引用上面定义的resultMap。
(4)在配置文件mybatis-config.xml中,引入UserMapper.xml。
(5)在测试类中,编写测试方法findAllUserTest(),代码如下所示。
@Test
public void findAllUserTest() {
// 获取SqlSession
SqlSession sqlSession = MybatisUtils.getSession();
// SqlSession执行映射文件中定义的SQL,并返回映射结果
List<User> list =
sqlSession.selectList("com.itheima.mapper.UserMapper.findAllUser");
for (User user : list) {
System.out.println(user);
}
// 关闭SqlSession
sqlSession.close();
}
使用JUnit4执行上述方法后,控制台的输出结果如图1所示。
图1 运行结果
从图1可以看出,虽然t_user表的列名与User对象的属性名完全不一样,但查询出的数据还是被正确的封装到了User对象中。
除此之外,还可以通过<resultMap>元素中的<association>和<collection>处理多表时的关联关系。关于关联关系的内容,将在教材第9章中详细讲解,这里就不再叙述。