MybatisPlus在用Collection标签查询时List中只出现一条记录

mybatis的collection标签查询,问题定位及解决方法。

问题:

在用mybatisPlus做关联查询时,发现list集合中只能显示出一条数据,且总是保持为第一条,而mybatis日志打印都是正确的。

日志打印如下:

==>  Preparing: select ui.id, ui.user_name, ui.pass_word, r.id r_id, r.role from user_info ui left join roles r on ui.id = r.id where ui.user_name = ? 
==> Parameters: zhangsan(String)
<==    Columns: id, user_name, pass_word, r_id, role
<==        Row: 3, zhangsan, 123456, 3, 1
<==        Row: 3, zhangsan, 123456, 3, 2
<==        Row: 3, zhangsan, 123456, 3, 3
<==      Total: 3

结果:

UserLoginInfoDto(id=3, username=zhangsan, password=123456, roles=[Role(id=3,

role=1)])

代码:

xml

<resultMap id="BaseResultMap" type="com.example.demo.dto.UserLoginInfoDto">
    <id column="id" property="id" />
    <result column="user_name" property="username" />
    <result column="pass_word" property="password" />
    <collection property="roles" ofType="com.example.demo.dto.Role">
        <id column="id" property="id" />
        <result column="role" property="role" />
    </collection>
</resultMap>
<select id="findByUsername" parameterType="java.lang.String" resultMap="BaseResultMap">
    select 
        * 
    from 
        user_info ui 
    left join roles r on ui.id=r.id 
    where ui.user_name = #{username}
</select>

mapper

UserLoginInfoDto findByUsername(@Param("username") String username);

问题定位及解决方法:

1.mybatisPlus在collection关联子表的情况下,如果主表主键ID的字段名与子表的主键ID字段一样的话,需要别名子表id字段

<resultMap id="BaseResultMap" type="com.example.demo.dto.UserLoginInfoDto">
    <id column="id" property="id" />
    <result column="user_name" property="username" />
    <result column="pass_word" property="password" />
    <collection property="roles" ofType="com.example.demo.dto.Role">
        <id column="r_id" property="id" />
        <result column="role" property="role" />
    </collection>
</resultMap>

<select id="getUserInfo" resultMap="BaseResultMap" parameterType="java.lang.String">
        select
            ui.id,
            ui.user_name,
            ui.pass_word,
            r.id r_id,
            r.role
        from user_info ui
            left join roles r on ui.id = r.id
        where ui.user_name = #{username}
</select>

 注意:column对应的是表字段名,别名之后应与别名保持一致

如果这种方法查出来的还是一条数据,还是不能解决问题,不要着急接着看

2.确定子表的主键字段,由于主表与子表为一对多的关系,在建立子表时很有可能没有指定子表主键,故在解决此问题时需要把collection标签中的<id column="id" property="id" />更改为<result column="id" property="id" />

<resultMap id="BaseResultMap" type="com.example.demo.dto.UserLoginInfoDto">
    <id column="id" property="id" />
    <result column="user_name" property="username" />
    <result column="pass_word" property="password" />
    <collection property="roles" ofType="com.example.demo.dto.Role">
        <result column="id" property="id" />
        <result column="role" property="role" />
    </collection>
</resultMap>

日志:

==>  Preparing: select ui.id, ui.user_name, ui.pass_word, r.id r_id, r.role from user_info ui left join roles r on ui.id = r.id where ui.user_name = ? 
==> Parameters: zhangsan(String)
<==    Columns: id, user_name, pass_word, r_id, role
<==        Row: 3, zhangsan, 123456, 3, 1
<==        Row: 3, zhangsan, 123456, 3, 2
<==        Row: 3, zhangsan, 123456, 3, 3
<==      Total: 3

 结果:

UserLoginInfoDto(id=3, username=zhangsan, password=123456, roles=[Role(id=3, role=1), Role(id=3, role=2), Role(id=3, role=3)])

 问题解决!!!