MyBatis 中 标签的这段配置
sql
<collection property="orders"
ofType="com.example.Order"
javaType="java.util.ArrayList">
...
</collection>
这是 MyBatis 用于处理 一对多(1:N)关联关系 的核心配置。下面逐项解析其含义,并结合例子说明。
作用
用于将数据库查询结果中的多行数据映射为 Java 对象中的一个集合属性(如 List、Set 等)。
在你这个例子中:
主对象(比如 User)有一个属性叫 orders,类型是 List。
MyBatis 会把与该主对象关联的多个 Order 记录自动收集起来,放入 orders 集合中。
property="orders"
表示主 Java 对象(如 User 类)中有一个名为 orders 的字段。
通常是 List、Set 等集合类型。
java
public class User {
private Long id;
private String name;
private List<Order> orders; // ← 这个字段
}
ofType="com.example.Order"
指定集合中每个元素的 Java 类型。
即:orders 这个列表里装的是 Order 对象。
MyBatis 会用这个类去创建每一个子对象,并映射字段。
ofType 是 最重要的属性之一,不能省略(除非使用注解或自动推断,但 XML 中强烈建议显式声明)
javaType="java.util.ArrayList"
指定集合本身的 Java 类型。
即:orders 这个字段具体是用 ArrayList 实现的(而不是 LinkedList 或 HashSet)。
注意:javaType 在大多数情况下可以省略,因为 MyBatis 默认会使用 ArrayList 作为 List 类型的实现。只有当你需要特定集合类型(如 HashSet)时才需显式指定。
demo
java
// 主对象
public class User {
private Long id;
private String name;
private List<Order> orders; // 一对多:一个用户有多个订单
// getters / setters
}
// 子对象
public class Order {
private Long orderId;
private String productName;
private BigDecimal amount;
// getters / setters
}
java
-- 用户表
CREATE TABLE user (
id BIGINT,
name VARCHAR(100)
);
-- 订单表
CREATE TABLE order (
order_id BIGINT,
user_id BIGINT,
product_name VARCHAR(100),
amount DECIMAL(10,2)
);
sql
<resultMap id="UserWithOrdersResult" type="com.example.User">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!-- 一对多映射 -->
<collection property="orders"
ofType="com.example.Order"
javaType="java.util.ArrayList">
<id column="order_id" property="orderId"/>
<result column="product_name" property="productName"/>
<result column="amount" property="amount"/>
</collection>
</resultMap>
sql
<select id="selectUserWithOrders" resultMap="UserWithOrdersResult">
SELECT
u.id,
u.name,
o.order_id,
o.product_name,
o.amount
FROM user u
LEFT JOIN order o ON u.id = o.user_id
WHERE u.id = #{userId}
</select>
java
User user = new User();
user.setId(1L);
user.setName("Alice");
List<Order> orders = new ArrayList<>();
Order o1 = new Order(); o1.setOrderId(101L); o1.setProductName("iPhone"); ...
Order o2 = new Order(); o2.setOrderId(102L); o2.setProductName("iPad"); ...
orders.add(o1);
orders.add(o2);
user.setOrders(orders); // 自动注入!
如果不用 JOIN,而是分两次查(嵌套查询)呢?
java
<collection property="orders"
ofType="com.example.Order"
select="selectOrdersByUserId"
column="id" />
此时 MyBatis 会先查用户,再用 id 去调用 selectOrdersByUserId 查询订单(可能产生 N+1 问题,需注意)
| 属性 | 作用 | 是否必需 |
|---|---|---|
property |
主对象中的集合字段名 | ✅ 必需 |
ofType |
集合中元素的类型(如 Order) |
✅ 必需(XML 中强烈建议) |
javaType |
集合本身的实现类(如 ArrayList) |
❌ 通常可省略 |