全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-20 6 分钟 ✍️ juanwangdev

@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 映射一对多关系,返回 List
  • select 属性指定子查询方法的完全限定名,格式 接口全路径.方法名
  • column 属性指定传递哪列数据给子查询,支持单列和多列({key=column} 格式)
  • fetchType 控制加载策略,建议关联查询使用 FetchType.LAZY 避免 N+1 性能问题
  • 多表 JOIN 查询也可用 @Results 直接映射,无需子查询,性能更优

📝 发现内容有误?点击此处直接编辑

← 上一篇 输入输出参数
下一篇 → @Results 结果映射
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库