✅ 一、核心概念

注解 作用说明
@Results 定义一组字段与实体类属性的映射关系,替代 XML 中的 <resultMap>
@Result 定义单个字段与属性的映射,支持主键、类型转换、关联查询等。
@ResultMap 复用已定义的 @Results,避免重复代码。
@One / @Many 用于一对一、一对多、多对一、多对多关联映射。

✅ 二、操作步骤(详细)

步骤1:定义实体类

@Data
public class User {
    private Integer id;
    private String username;
    private Integer age;
    private Date birthDate; // 数据库中为 VARCHAR
}

步骤2:定义 Mapper 接口

@Mapper
public interface UserMapper extends BaseMapper<User> {

    // 字段名与属性名不一致时,使用 @Results 映射
    @Select("SELECT id, user_name, age, birth_date FROM tab_user")
    @Results({
        @Result(property = "id", column = "id", id = true),
        @Result(property = "username", column = "user_name"),
        @Result(property = "birthDate", column = "birth_date", javaType = Date.class, jdbcType = JdbcType.VARCHAR)
    })
    List<User> selectAllUsers();

    // 使用 @ResultMap 复用映射
    @ResultMap("userMap")
    @Select("SELECT id, user_name, age, birth_date FROM tab_user WHERE id = #{id}")
    User selectUserById(Integer id);
}

步骤3:定义可复用的 @Results(可选)

@Results(id = "userMap", value = {
    @Result(property = "id", column = "id", id = true),
    @Result(property = "username", column = "user_name"),
    @Result(property = "birthDate", column = "birth_date")
})
@Select("SELECT * FROM tab_user")
List<User> selectAllWithMap();

✅ 三、常见错误与排查

错误提示 原因 解决
Invalid bound statement (not found) 未加 @Select / @Mapper 注解 检查注解是否完整
字段映射失败 属性名与列名不一致,未配置 @Result 显式配置 @Results
类型转换失败 数据库字段与 Java 类型不匹配 使用 javaTypejdbcType 明确指定

✅ 四、注意事项

  1. 驼峰自动映射:若开启 map-underscore-to-camel-case=true,可省略部分映射。
  2. @Results 不继承:每个方法需单独配置,除非使用 @ResultMap
  3. 性能建议:避免在大量查询中使用复杂嵌套 @One/@Many,建议用分页或懒加载。

✅ 五、使用技巧

场景 技巧
字段名不一致 使用 @Result(column="xxx", property="xxx")
类型转换 使用 javaTypejdbcType
多表关联 使用 @One(select="...")@Many(select="...")
避免重复 @Resultsid,用 @ResultMap("id") 复用

✅ 六、最佳实践与性能优化

实践建议 说明
优先使用 @ResultMap 复用 减少重复代码,提升可维护性
避免 N+1 查询问题 使用 @Many 时注意懒加载或分页
避免复杂嵌套注解 复杂 SQL 建议使用 XML 或 @SelectProvider
开启日志调试 配置 logging.level.com.xxx.mapper=debug 查看实际 SQL

✅ 示例:一对多查询(用户与订单)

// UserVO.java
@Data
public class UserVO {
    private Integer id;
    private String name;
    private List<Order> orders;
}

// UserMapper.java
@Results({
    @Result(property = "id", column = "id"),
    @Result(property = "name", column = "name"),
    @Result(property = "orders", column = "id", many = @Many(select = "com.xxx.mapper.OrderMapper.selectByUserId"))
})
@Select("SELECT id, name FROM t_user")
List<UserVO> selectUserWithOrders();

✅ 总结一句话

@Results 是注解版的 <resultMap>,@Result 是字段映射的核心单元,结合 @ResultMap、@One/@Many 可实现复杂映射与多表查询,适合轻量级项目快速开发。