@One 与 @Many 关联
MyBatis 注解模式下,关联查询通过 @One(一对一)和 @Many(一对多)配合 @Results 实现,替代 XML 中的 <association> 和 <collection>。
@One 一对一关联
@One 用于映射一对一关系,通过 select 属性指定子查询方法。
基本用法
Java
public interface UserMapper {
@Select("SELECT * FROM users WHERE id = #{id}")
@Results({
@Result(id = true, column = "id", property = "id"),
@Result(column = "name", property = "name"),
@Result(column = "dept_id", property = "department",
one = @One(select = "com.example.mapper.DepartmentMapper.getById"))
})
User findUserWithDepartment(@Param("id") Long id);
}
子查询 Mapper:
Java
public interface DepartmentMapper {
@Select("SELECT * FROM departments WHERE id = #{id}")
Department getById(@Param("id") Long id);
}
column 传参
column 属性指定将查询结果中的哪一列作为子查询参数:
| column 值 | 说明 | 子查询参数名 |
|---|---|---|
"dept_id" | 单列传参 | #{id} 接收 dept_id 值 |
{deptId=dept_id, status=status} | 多列传参 | #{deptId}, #{status} |
多列传参示例:
Java
@Result(column = "{deptId=dept_id, status=status}", property = "department",
one = @One(select = "com.example.mapper.DepartmentMapper.getByCondition"))
对应子查询:
Java
@Select("SELECT * FROM departments WHERE id = #{deptId} AND status = #{status}")
Department getByCondition(Map<String, Object> params);
@Many 一对多关联
@Many 用于映射一对多关系,返回类型为 List。
基本用法
Java
public interface DepartmentMapper {
@Select("SELECT * FROM departments WHERE id = #{id}")
@Results({
@Result(id = true, column = "id", property = "id"),
@Result(column = "name", property = "name"),
@Result(column = "id", property = "employees",
many = @Many(select = "com.example.mapper.EmployeeMapper.getByDeptId"))
})
Department findDeptWithEmployees(@Param("id") Long id);
}
子查询 Mapper:
Java
public interface EmployeeMapper {
@Select("SELECT * FROM employees WHERE dept_id = #{deptId}")
List<Employee> getByDeptId(@Param("deptId") Long deptId);
}
延迟加载
关联查询默认立即执行,可通过 fetchType 控制加载策略:
Java
@Result(column = "id", property = "employees",
many = @Many(
select = "com.example.mapper.EmployeeMapper.getByDeptId",
fetchType = FetchType.LAZY))
| fetchType 值 | 说明 |
|---|---|
FetchType.DEFAULT | 跟随全局配置 |
FetchType.LAZY | 延迟加载,访问属性时才执行子查询 |
FetchType.EAGER | 立即加载,查询时一并执行子查询 |
全局配置开启延迟加载:
YAML
mybatis:
configuration:
lazy-loading-enabled: true
aggressive-lazy-loading: false
嵌套关联示例
一对一 + 一对多同时存在:
Java
@Select("SELECT * FROM orders WHERE id = #{id}")
@Results({
@Result(id = true, column = "id", property = "id"),
@Result(column = "user_id", property = "user",
one = @One(select = "com.example.mapper.UserMapper.getById")),
@Result(column = "id", property = "items",
many = @Many(select = "com.example.mapper.OrderItemMapper.getByOrderId"))
})
Order findOrderWithUserAndItems(@Param("id") Long id);
要点总结
@One映射一对一关系,返回单个对象;@Many映射一对多关系,返回Listselect属性指定子查询方法的完全限定名,格式接口全路径.方法名column属性指定传递哪列数据给子查询,支持单列和多列({key=column}格式)fetchType控制加载策略,建议关联查询使用FetchType.LAZY避免 N+1 性能问题- 多表 JOIN 查询也可用
@Results直接映射,无需子查询,性能更优
📝 发现内容有误?点击此处直接编辑