Mybatis结果集映射

概述

结果映射指的是将数据表中的字段与实体类中的属性关联起来,这样 MyBatis 就可以根据查询到的数据来填充实体对象的属性,帮助我们完成赋值操作。

简单结果映射

使用Map映射

resultType设置为map,会将列名映射为map的key,值为map的value,当值为null时,该key不会在结果map中存在。

1
2
3
<select id="getUser" resultType="map">
SELECT id, username FROM user WHERE id = #{id}
</select>

使用JavaBean

MyBatis 会自动将查询结果中的列名与 Java 对象的属性名进行匹配,然后自动映射结果集到对象中。需要保证查询结果中的列名与对象的属性名一致。

比如数据库的字段名和实体类的属性名相同时,可以直接在xml头标签中使用resultType指定实体类来映射。

实体类:

1
2
3
4
5
@Data
public class User {
private int id;
private String username;
}

mapper.xml:

1
2
3
<select id="getUser" resultType="User">
SELECT id, username FROM user WHERE id = #{id}
</select>

当实体类属性名和数据库字段名不一致时,也可以通过AS别名进行映射。

1
2
3
<select id="getUser" resultType="User">
SELECT id, user_name as username FROM user WHERE id = #{id}
</select>

resultMap映射

通过在映射文件中定义 resultMap,可以手动指定查询结果与 Java 对象之间的映射关系。可以灵活地配置列名、属性名、类型转换等。

mapper.xml:

1
2
3
4
5
6
7
8
<resultMap id="userMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name" />
</resultMap>

<select id="getUser" resultMap="userMap">
SELECT user_id, user_name FROM user WHERE id = #{id}
</select>

通过id指定resultMap,其中property为type设置实体类的属性名,column是数据库字段名。

嵌套结果映射

当查询结果中存在多个对象关联时,可以使用嵌套结果映射来将结果集映射到多个对象的关联关系中。可以通过 <association><collection> 标签来定义对象之间的关系。

association使用

<association>用于将查询结果中的一行数据映射到一个关联对象上。它适用于一对一的关联关系。

实体类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Data
public class Order {
private int id;
private String orderNo;
private int userId;
private User user;
}

@Data
public class User {
private int id;
private String username;
private String email;
}

mapper.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<resultMap id="orderResultMap" type="Order">
<id property="id" column="id" />
<result property="orderNo" column="order_no" />
<result property="userId" column="user_id" />
<association property="user" javaType="User">
<id property="id" column="user_id" />
<result property="username" column="username" />
<result property="email" column="email" />
</association>
</resultMap>

// 查询语句
<select id="getOrder" resultMap="orderResultMap">
SELECT u.username, u.email, o.order_no
FROM user u
INNER JOIN order o ON u.user_id = o.user_id
WHERE u.id = #{id}
</select>

collection使用

<collection>用于将查询结果中的多行数据映射到一个集合属性上。它适用于一对多的关联关系。

实体类:

1
2
3
4
5
6
7
8
9
10
11
12
@Data
public class User {
private int id;
private String username;
private List<Order> orders;
}

@Data
public class Order {
private int orderId;
private String orderName;
}

mapper.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<resultMap id="userMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name" />
<collection property="orders" ofType="Order">
<id property="orderId" column="order_id" />
<result property="orderName" column="order_name" />
</collection>
</resultMap>

// 查询语句
<select id="getUser" resultMap="userMap">
SELECT u.user_id, u.user_name, o.order_id, o.order_name
FROM user u
INNER JOIN order o ON u.user_id = o.user_id
WHERE u.id = #{id}
</select>

嵌套使用

实体类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Data
public class User {
private int id;
private String username;
private List<Order> orders;
private Role role;
}

@Data
public class Order {
private int id;
private String orderName;
}

@Data
public class Role {
private int id;
private String roleName;
}

mapper.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<resultMap id="userMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name" />
<association property="role" column="id" javaType="Role" resultMap="roleResult" />
<collection property="orders" javaType="java.util.List" resultMap="orderResult"/>
</resultMap>

<resultMap id="roleResult" type="Role">
<id property="id" column="role_id" />
<result property="roleName" column="role_name" />
</resultMap>

<resultMap id="orderResult" type="Order">
<id property="id" column="order_id" />
<result property="orderName" column="order_name" />
</resultMap>

// 查询语句
<select id="getUser" resultMap="userMap">
SELECT u.user_id, u.user_name,
r.role_id, r.role_name,
o.order_id, o.order_name
FROM user u
LEFT JOIN role r ON u.role_id = r.role_id
LEFT JOIN orders o ON u.user_id = o.user_id
WHERE u.user_id = #{userId}
</select>