MyBatis @Result和@Many注解详解:关联查询与映射配置教程

 更新时间:2026年07月17日 11:05:19   作者:三水写代码  
还在为MyBatis注解配置关联查询而头疼?本文深入解析@Results、@Result和@Many注解,手把手教你配置一对多查询和参数传递,结合@ResultMap复用映射,让你的代码更简洁高效

MyBatis @Result和@Many注解

先来看一组代码:

@Results(id="groupWithUsers",
         value = { 
            @Result(property = "groupId", column = "group_id", id = true),
            @Result(property = "name", column = "name"), 
            @Result(property = "accountId", column = "account_id"),
            @Result(property = "deleteFlag", column = "delete_Flag"),
            @Result(property = "parentId", column = "parent_Id"), 
            @Result(property = "userList", javaType=List.class, many =@Many(select="selectUsersByGroupId"), column = "group_id")})
//查询
@Select({"select * from group where account_id=#{accountId} and delete_flag=0"})
List<Group> selectGroupWithUsers(@Param("accountId") String accountId);
@Select({"select u.* from user u",
		"inner join user_group ug on u.user_id = ug.user_id",
		"where ug.group_id=#{groupId} and u.delete_flag=0"
		})
List<User> selectUsersByGroupId(@Param("groupId") String groupId);

我们的接受的对象Group中的字段:(User类中的映射关系这里就不再赘述)

@Data
public class Group {
    private String groupId;
    private String name;
    private String accountId;
    private String parentId;
    private String type;
    private List<User> userList;
}

调用List<Group> selectGroupWithUsers(@Param("accountId") String accountId);查出的结果为:

从结果中可以看出,查询出的列和Group中属性信息的映射关系是在@Results中value属性的@Result注解进行配置的,这里与mybatis的xml配置文件开发基本相同。

再看一下userList包含了user信息,也就是selectUsersByGroupId方法被调用,查询结果被封装在Group类中的userList字段中。而selectUsersByGroupId方法被调用的配置在@Many注解中。

下面我们来卓层分析一下@Results注解及注解中的属性信息:

@Results注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Results {
    String id() default "";  //当前Results注解的唯一标识
    Result[] value() default {};  //value值为Result[]数组
}

@Results中只有两个属性,id和value,id作为当前@Results注解的唯一标识很好理解;value值为@Result数组,下面我们看一下@Result的信息:

@Result

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Result {
    boolean id() default false;  //id唯一标识
    String column() default "";  //对应数据库中的列名
    String property() default ""; //对应类中的属性名
    Class<?> javaType() default void.class;  //数据类型
    JdbcType jdbcType() default JdbcType.UNDEFINED;  //jdbc类型
    Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;
    One one() default @One;  //一对一配置
    Many many() default @Many;  //一对多配置
}

@Result中常用的属性是column和property,用于配置数据库中的列名和类中的属性名之间的映射关系。另外one和many用于关联查询。

比如上面列子中提到的Group类中包含属性List<User> userList,这时集合类型数据,与Group是一对多的关系,需要用many配置,如果Group中需要对象类型数据User user,那么就需要使用one进行配置。

这里我们以many为例进行说明:

@Result中many的应用

@Many:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Many {
    String select() default "";  //选择要执行的方法
    FetchType fetchType() default FetchType.DEFAULT;  //枚举值,懒加载、及时加载、默认
}

@Many中常用的属性只有selet,用于指定关联查询的方法

但是存在many属性的@Result注解的使用就有些变化:如下面的这段代码中,column属性的值为"group_id",是group表中的列,也是作为参数传递到selectUsersByGroupId中进行查询的参数。

@Result(property = "userList", javaType=List.class, many =@Many(select="selectUsersByGroupId"), column = "group_id")})

如果select属性指定的方法需要的参数是一个对象,要如何传递参数?比如select属性绑定的是如下方法:

public List<User> selectUsers(Map<String,Object> map);

需要的参数是一个Map对象,这时column属性的值要设置为:

column = "{groupId=group_id, userName=user_name}"

这时,就相当于我们在map中传入了两个值map.put("groupId",value) ,map.put("userName",value),而column中,“groupId=group_id”,相当于将库中的列group_id映射到groupId中,user_name也一样。

至此,@Resuts和@Result的使用大致就这些,那么@ResultMap注解的使用,其实就是引用已定义好的@Results

@ResultMap

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface ResultMap {
    String[] value();
}

@ResultMap中只有一个属性value,用于指定要引用的@Results,value值为@Results的id值,如下所示:

@ResultMap("resultsId")
@Select("......")
List<Object> select();

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring中的编程式事务和声明式事务

    Spring中的编程式事务和声明式事务

    Spring框架中,事务管理可以通过编程式事务和声明式事务两种方式实现,编程式事务通过手动编码控制事务的开始、提交和回滚,允许开发者精确控制事务,但增加了代码复杂度,声明式事务则通过@EnableTransactionManagement注解启用事务管理
    2024-11-11
  • Java及数据库对日期进行格式化方式

    Java及数据库对日期进行格式化方式

    这篇文章主要介绍了Java及数据库对日期进行格式化方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • java实现轻量型http代理服务器示例

    java实现轻量型http代理服务器示例

    这篇文章主要介绍了java实现轻量型http代理服务器示例,需要的朋友可以参考下
    2014-04-04
  • iReport简单使用方法图文教程

    iReport简单使用方法图文教程

    iReport是一个能够创建复杂报表的开源项目,它100%使用Java语言编写,是目前全球最为流行的开源报表设计器,由于它丰富的图形界面,你能够很快的创建出任何一种你想要的报表
    2021-10-10
  • springboot相关面试题汇总详解

    springboot相关面试题汇总详解

    这篇文章主要介绍了springboot相关面试题汇总详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • SpringBoot 获取请求参数的常用注解及用法

    SpringBoot 获取请求参数的常用注解及用法

    Spring Boot通过@RequestParam、@PathVariable等注解支持从HTTP请求中获取参数,涵盖查询、路径、请求体、头、Cookie等类型,还可绑定到对象或使用Servlet API,需注意参数匹配规则及配置支持隐藏方法过滤器,本文介绍SpringBoot获取请求参数的常用注解,感兴趣朋友一起看看吧
    2025-07-07
  • Java宽化基本类型转换与精度丢失详解(为什么long可以自动转float)

    Java宽化基本类型转换与精度丢失详解(为什么long可以自动转float)

    java中long到float的转换属于自动类型转换,因为float的范围比long更大,这篇文章主要介绍了Java宽化基本类型转换与精度丢失的相关资料,详细介绍了为什么long可以自动转float,需要的朋友可以参考下
    2026-05-05
  • idea的使用之关于tomcat热部署的教程

    idea的使用之关于tomcat热部署的教程

    这篇文章主要介绍了idea的使用之关于tomcat热部署的教程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • springboot项目使用SchedulingConfigurer实现多个定时任务的案例代码

    springboot项目使用SchedulingConfigurer实现多个定时任务的案例代码

    这篇文章主要介绍了springboot项目使用SchedulingConfigurer实现多个定时任务,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-01-01
  • Java网络通信中ServerSocket的设计优化方案

    Java网络通信中ServerSocket的设计优化方案

    今天小编就为大家分享一篇关于Java网络通信中ServerSocket的设计优化方案,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04

最新评论