<resultMap>详解
在 MyBatis 的 <resultMap>
中,<association>
标签用于处理一对一的关联映射,也就是一个实体对象关联另一个实体对象的情况。下面为你详细解释 <association>
标签里各个属性的含义:
1. property
1. property
-
作用:该属性指定了当前实体类中用于关联另一个实体对象的属性名。在这个例子里,
property="partner"
意味着在当前的实体类(可能是NodeVo
)中有一个名为partner
的属性,它的类型是Partner
类,用于存储关联的合作伙伴信息。 -
示例:假设
NodeVo
类的定义如下:
java
public class NodeVo { // 其他属性... private Partner partner; // getter 和 setter 方法 }
这里的 partner
属性就对应 <association>
标签中的 property
属性。
2. javaType
-
作用:它明确了关联对象的 Java 类型。在这个例子中,
javaType="Partner"
表明关联的对象是Partner
类的实例。MyBatis 会依据这个类型来创建和填充关联对象。 -
示例:
Partner
类可能是这样定义的:
java
public class Partner { private Long id; private String name; // 其他属性和 getter、setter 方法 }
MyBatis 会根据查询结果将数据填充到 Partner
类的实例中,并将其赋值给 NodeVo
类的 partner
属性。
3. column
-
作用:该属性指定了用于关联查询的列名。在这个例子中,
column="partner_id"
表示使用当前查询结果中的partner_id
列的值作为参数,去执行select
属性指定的 SQL 查询。 -
示例:在主查询中,会查询出
partner_id
列的值,然后将这个值作为参数传递给com.dkd.manage.mapper.PartnerMapper.selectPartnerById
方法。
4. select
-
作用:它指定了用于查询关联对象的 SQL 语句的 ID。在这个例子中,
select="com.dkd.manage.mapper.PartnerMapper.selectPartnerById"
表示会调用PartnerMapper
接口中id
为selectPartnerById
的查询方法,使用column
属性指定的列的值作为参数进行查询。 -
示例:
PartnerMapper.xml
中可能有如下查询语句:
xml
<select id="selectPartnerById" parameterType="Long" resultType="Partner"> SELECT * FROM tb_partner WHERE id = #{id} </select>
MyBatis 会将 partner_id
的值作为参数传递给这个查询方法,查询出对应的 Partner
对象,并将其赋值给 NodeVo
类的 partner
属性。
综上所述,<association>
标签通过这些属性实现了在查询结果中关联另一个实体对象的功能,使得我们可以方便地处理复杂的对象关系。
总结
<association>
标签用于 MyBatis 的 <resultMap>
中处理一对一关联映射,其属性含义如下:
-
property
:指定当前实体类中用于关联另一个实体对象的属性名,关联信息将存储在此属性中。 -
javaType
:明确关联对象的 Java 类型,MyBatis 据此创建和填充关联对象。 -
column
:指定用于关联查询的列名,该列的值会作为参数用于执行select
属性指定的 SQL 查询。 -
select
:指定用于查询关联对象的 SQL 语句的 ID,MyBatis 会用column
属性指定列的值作为参数执行此查询,并将结果赋值给property
指定的属性。
collection的总结
在 MyBatis 的 <resultMap>
中,<collection>
标签用于处理一对多的关联映射,也就是一个实体对象关联多个其他实体对象的情况。以下是 <collection>
标签各属性及功能的总结:
主要作用
<collection>
标签允许你将查询结果中的多行数据映射到一个 Java 对象的集合属性中,实现复杂的对象关系映射。
常用属性及含义
1. property
-
作用:指定当前实体类中用于存储关联对象集合的属性名。MyBatis 会将查询到的关联对象集合赋值给该属性。
-
示例:若有一个
Order
类,其中有一个List<OrderItem>
类型的orderItems
属性,在<resultMap>
中可通过property="orderItems"
来关联订单明细集合。
2. javaType
-
作用:明确集合属性的 Java 类型,通常为
java.util.List
或java.util.Set
等。虽然大多数情况下可省略,MyBatis 能自动推断,但显式指定可增强代码可读性。 -
示例:
javaType="java.util.List"
3. ofType
3. ofType
-
作用:指定集合中元素的 Java 类型,即关联对象的类型。MyBatis 会根据此类型创建和填充集合中的每个元素。
-
示例:若集合中存储的是
OrderItem
对象,则ofType="com.example.OrderItem"
4. column
4. column
-
作用:指定用于关联查询的列名。与
<association>
类似,此列的值会作为参数传递给嵌套查询或用于连接查询。 -
示例:在查询订单及其明细时,
column="order_id"
表示使用订单 ID 作为关联条件查询对应的订单明细。
5. select
-
作用:指定用于查询关联对象集合的 SQL 语句的 ID。MyBatis 会使用
column
属性指定的列的值作为参数执行该查询,并将结果填充到集合中。 -
示例:
select="com.example.mapper.OrderItemMapper.selectByOrderId"
6. fetchType
6. fetchType
-
作用:可选属性,用于指定关联对象集合的加载方式,有
lazy
(懒加载)和eager
(立即加载)两种取值。 -
示例
:
-
fetchType="lazy"
:当访问集合属性时才会执行关联查询。 -
fetchType="eager"
:在主查询执行时就会立即执行关联查询。
-
应用场景
<collection>
标签常用于处理具有一对多关系的数据库表,如订单与订单明细、部门与员工等。通过使用 <collection>
标签,可以方便地将查询结果映射到 Java 对象的集合属性中,避免手动处理复杂的对象关系。
示例代码片段
xml
<resultMap id="OrderResultMap" type="com.example.Order"> <id property="id" column="order_id"/> <result property="orderNo" column="order_no"/> <collection property="orderItems" ofType="com.example.OrderItem" column="order_id" select="com.example.mapper.OrderItemMapper.selectByOrderId"> </collection> </resultMap>
在上述示例中,Order
对象通过 <collection>
标签关联了多个 OrderItem
对象,MyBatis 会根据订单 ID 执行 OrderItemMapper
中的 selectByOrderId
方法,将查询结果填充到 Order
对象的 orderItems
属性中。
分享
举例说明如何在MyBatis中使用collection标签进行一对多关联映射
collection标签的fetchType属性有什么作用?
在MyBatis中如何配置collection标签的延迟加载?
下面通过一个具体的示例,详细介绍如何在 MyBatis 里运用 <collection>
标签实现一对多关联映射。假设我们有两个实体类:Department
(部门)和 Employee
(员工),一个部门可以有多个员工,这就是典型的一对多关系。
1. 定义实体类
Department.java
java
举例说明如何在MyBatis中使用collection标签进行一对多关联映射
import java.util.List; public class Department { private Integer id; private String name; private List<Employee> employees; // 构造函数、getter 和 setter 方法 public Department() {} public Department(Integer id, String name) { this.id = id; this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Employee> getEmployees() { return employees; } public void setEmployees(List<Employee> employees) { this.employees = employees; } }
Employee.java
java
public class Employee { private Integer id; private String name; private Integer departmentId; // 构造函数、getter 和 setter 方法 public Employee() {} public Employee(Integer id, String name, Integer departmentId) { this.id = id; this.name = name; this.departmentId = departmentId; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getDepartmentId() { return departmentId; } public void setDepartmentId(Integer departmentId) { this.departmentId = departmentId; } }
2. 定义 Mapper 接口
DepartmentMapper.java
java
import java.util.List; public interface DepartmentMapper { Department getDepartmentById(Integer id); }
3. 编写 Mapper XML 文件
DepartmentMapper.xml
xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.mapper.DepartmentMapper"> <resultMap id="DepartmentResultMap" type="com.example.entity.Department"> <id property="id" column="department_id"/> <result property="name" column="department_name"/> <collection property="employees" ofType="com.example.entity.Employee"> <id property="id" column="employee_id"/> <result property="name" column="employee_name"/> <result property="departmentId" column="department_id"/> </collection> </resultMap> <select id="getDepartmentById" parameterType="int" resultMap="DepartmentResultMap"> SELECT d.id AS department_id, d.name AS department_name, e.id AS employee_id, e.name AS employee_name, e.department_id FROM department d LEFT JOIN employee e ON d.id = e.department_id WHERE d.id = #{id} </select> </mapper>
代码解释
-
实体类:
Department
类包含一个List<Employee>
类型的employees
属性,用于存储该部门下的所有员工。 -
Mapper 接口:
DepartmentMapper
接口定义了一个getDepartmentById
方法,用于根据部门 ID 查询部门信息及其关联的员工信息。 -
Mapper XML 文件
:
-
<resultMap>
标签定义了DepartmentResultMap
,用于将查询结果映射到Department
对象。 -
<collection>
标签用于处理一对多关联映射,property="employees"
表示将关联的员工信息映射到Department
对象的employees
属性中,ofType="com.example.entity.Employee"
表示集合中的元素类型为Employee
。 -
<select>
标签定义了查询语句,使用LEFT JOIN
关联department
表和employee
表,根据部门 ID 查询部门信息及其关联的员工信息,并使用DepartmentResultMap
进行结果映射。
-
4. 调用示例
java
import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.InputStream; public class Main { public static void main(String[] args) throws Exception { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); try (SqlSession session = sqlSessionFactory.openSession()) { DepartmentMapper departmentMapper = session.getMapper(DepartmentMapper.class); Department department = departmentMapper.getDepartmentById(1); System.out.println("部门名称: " + department.getName()); System.out.println("部门员工:"); for (Employee employee : department.getEmployees()) { System.out.println(" - " + employee.getName()); } } } }
代码解释
-
此示例代码展示了如何使用 MyBatis 从数据库中查询部门信息及其关联的员工信息,并将结果打印输出。
-
通过
SqlSessionFactory
创建SqlSession
,然后获取DepartmentMapper
接口的实例,调用getDepartmentById
方法进行查询。
通过以上步骤,你就可以在 MyBatis 中使用 <collection>
标签实现一对多关联映射。