Mybatis一对多遇到的坑

最近项目中使用到mybatis的一对多的功能,需求是查找特定用户对应的所有角色和权限

涉及的实体类

用户类

public class User {
    private Long id;
    private String userId;
    private String name;
    private String mobile;
    private String role;
    private Set<Role> roleSet = new HashSet<>();

    //ommitted getter/setter
}

角色类

public class Role {
    private Long id;
    private String name;
    private String description;
    private Set<Permission> permissionSet = new HashSet<>();

    //ommitted getter/setter
}

权限类

public class Permission {
    private Long id;

    private String name;

    private String description;

    //ommitted getter/setter
}

mapper文件配置

<resultMap id="ResultMapWithRolePerms" type="user" >
    <id column="id" property="id" jdbcType="BIGINT" />
    <result column="user_id" property="userId" jdbcType="VARCHAR" />
    <result column="name" property="name" jdbcType="VARCHAR" />
    <collection property="roleSet" ofType="role">
      <id property="id" column="role_id"/>
      <result property="name" column="role_name"/>
      <collection property="permissionSet" ofType="permission">
        <id property="id" column="perm_id"/>
        <result property="name" column="perm_name"/>
      </collection>
    </collection>

  </resultMap>

<select id="findUserById" parameterType="string" resultMap="ResultMapWithRolePerms">
  SELECT 
    u.user_id user_id,
    u.name name,
    u.mobile mobile,
    r.id role_id,
    r.name role_name,
    p.id perm_id,
    p.name perm_name
FROM
    user AS u
        LEFT JOIN
    user_role AS ur ON (u.user_id = ur.user_id)
        LEFT JOIN
    role AS r ON (r.id = ur.role_id)
        LEFT JOIN
    role_perm AS rp ON (r.id = rp.role_id)
        LEFT JOIN
    permission AS p ON (p.id = rp.perm_id)
WHERE
    u.user_id = #{userId};
</select>

mapper查询方法

User findUserById(String userId);

运行结果

严重: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3] with root cause
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:81)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:434)
    at com.sun.proxy.$Proxy57.selectOne(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:167)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:75)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:53)

参考源码分析后,发现方法的返回值需要为List,即改为如下

List<User> findUserById(String userId);

总结

在使用一对多功能时,无论要查询的结果的主体是否唯一,返回值必须设为集合类,否则不会生效。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值