在MyBatis中,高级多表查询通常涉及到ResultMap、association以及collection这三个核心概念。它们共同构成了MyBatis处理复杂查询结果和对象关系映射的重要机制。以下是对这三个概念的详细解析:
一、ResultMap
ResultMap是MyBatis中一个强大的特性,它允许开发者手动定义数据库表字段与Java实体类属性之间的映射关系。这种映射关系对于处理复杂数据结构或字段名称不匹配的情况尤为重要。
- 定义:ResultMap通过XML配置文件来定义,包括id、type、result等标签。其中,id用于唯一标识ResultMap,type指定映射的Java实体类,result则用于定义具体的字段映射关系。
- 使用场景:当数据库表字段与Java实体类属性名称不一致,或者需要处理复杂的数据结构(如嵌套对象、集合等)时,可以使用ResultMap进行手动映射。
- 示例:
<resultMap id="empBaseMap" type="com.javatest.entity.Emp">
<id property="empno" column="empno"/>
<result property="ename" column="ename"/>
<result property="job" column="job"/>
<!-- 其他字段映射 -->
</resultMap>
二、association
association标签用于处理“一对一”或“多对一”的关系映射。它通常嵌套在ResultMap内部,用于将另一个表(或查询)的结果映射到一个复杂类型的属性上。
- 属性:
- property:指定映射到哪个Java对象的属性。
- javaType:指定该属性的Java类型。
- column:指定数据库中的哪一列用于作为外键(或关联字段)。
- select:指定一个用于加载关联对象的子查询ID(支持懒加载)。
- fetchType:指定加载策略(默认为eager,即预加载;也可以设置为lazy,即懒加载)。
- 使用场景:当需要查询一个对象及其关联的另一个对象时(如用户及其所属的部门),可以使用association进行映射。
- 示例:
<resultMap id="userResultMap" type="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<association property="department" javaType="Department" column="department_id" select="getDepartmentById"/>
</resultMap>
三、collection
collection标签用于处理“一对多”的关系映射。它同样嵌套在ResultMap内部,用于将多个结果行映射到一个集合或数组上。
- 属性:
- property:指定映射到哪个Java对象的属性(通常是一个集合或数组)。
- ofType:指定集合或数组中元素的类型。
- column:指定数据库中的哪一列用于作为外键(或关联字段)。
- foreignColumn:指定关联表中哪一列是外键(通常用于联表查询)。
- select:指定一个用于加载关联对象的子查询ID(支持懒加载)。
- fetchType:指定加载策略(默认为eager,即预加载;也可以设置为lazy,即懒加载)。
- 使用场景:当需要查询一个对象及其关联的多个对象时(如订单及其包含的订单项),可以使用collection进行映射。
- 示例:
<resultMap id="orderResultMap" type="Order">
<id property="id" column="id"/>
<result property="orderDate" column="order_date"/>
<collection property="orderItems" ofType="OrderItem" column="id" foreignColumn="order_id" select="getOrderItemsByOrderId"/>
</resultMap>
四、综合示例
假设有两个表:t_customer(客户表)和t_order(订单表),它们之间存在一对多的关系(一个客户可以有多个订单)。以下是一个综合示例,展示了如何使用ResultMap、association和collection进行多表查询。
- 实体类定义:
public class Customer {
private Integer customerId;
private String customerName;
private List<Order> orderList; // 订单列表
// Getters and Setters
}
public class Order {
private Integer orderId;
private String orderName;
private Integer customerId; // 外键,关联客户
// Getters and Setters
}
- Mapper接口定义:
public interface CustomerMapper {
Customer selectCustomerWithOrderList(Integer customerId);
}
- Mapper XML配置文件:
<resultMap id="selectCustomerWithOrderListResultMap" type="Customer">
<id property="customerId" column="customer_id"/>
<result property="customerName" column="customer_name"/>
<collection property="orderList" ofType="Order">
<id property="orderId" column="order_id"/>
<result property="orderName" column="order_name"/>
<result property="customerId" column="customer_id"/> <!-- 这里虽然设置了,但通常不需要在Order实体中使用 -->
</collection>
</resultMap>
<select id="selectCustomerWithOrderList" resultMap="selectCustomerWithOrderListResultMap">
SELECT c.customer_id, c.customer_name, o.order_id, o.order_name
FROM t_customer c
LEFT JOIN t_order o ON c.customer_id = o.customer_id
WHERE c.customer_id = #{customerId}
</select>
在这个示例中,我们通过ResultMap定义了Customer和Order之间的映射关系,并使用collection标签将多个订单映射到Customer的orderList属性上。然后,在select语句中通过联表查询获取客户和订单的数据。
综上所述,MyBatis中的ResultMap、association和collection提供了强大的多表查询和对象关系映射能力。通过合理使用这些特性,可以高效地处理复杂的数据结构和对象关系。
暂无评论内容