✅ 一、核心概念
注解 |
作用说明 |
@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 类型不匹配 |
使用 javaType 和 jdbcType 明确指定 |
✅ 四、注意事项
- 驼峰自动映射:若开启
map-underscore-to-camel-case=true
,可省略部分映射。
- @Results 不继承:每个方法需单独配置,除非使用
@ResultMap
。
- 性能建议:避免在大量查询中使用复杂嵌套
@One/@Many
,建议用分页或懒加载。
✅ 五、使用技巧
场景 |
技巧 |
字段名不一致 |
使用 @Result(column="xxx", property="xxx") |
类型转换 |
使用 javaType 和 jdbcType |
多表关联 |
使用 @One(select="...") 或 @Many(select="...") |
避免重复 |
给 @Results 加 id ,用 @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 可实现复杂映射与多表查询,适合轻量级项目快速开发。