Mybatis使用collection映射一对多查询分页问题详解

 更新时间:2025年12月04日 09:20:17   作者:小柒v  
本文通过修改SQL查询语句,解决了在分页条件下关联查询多表时,多的一端数据不正确的问题,从而实现了正常的展示

Mybatis使用collection映射一对多查询分页

场景

页面展示列表,需要关联查询另外1张表多的字段,分页。

/**
     * 标签
     */
    private List<BasicResidentTags> tags;
@Data
@TableName("basic_resident_tags")
public class BasicResidentTags{

    private static final long serialVersionUID=1L;

    /**
     * 标签id
     */
    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;
    /**
     * 名称
     */
    private String name;
    /**
     * 颜色
     */
    private String color;
    /**
     * 居民id
     */
    private Integer residentId;

}

原来的sql这样写

<!--一对多映射-->
    <resultMap id="many" type="com.vkl.basic.domain.vo.admin.BasicResidentListVo">
        <id property="residentId" column="resident_id"/>
        <result property="name" column="name"/>
        <result property="sex" column="sex"/>
        <result property="houseHolder" column="house_holder"/>
        <result property="residentName" column="resident_name"/>
        <result property="outsider" column="outsider"/>
        <result property="room" column="room"/>
        <collection property="tags" ofType="com.vkl.basic.domain.BasicResidentTags">
            <id column="tagsId" property="id"></id>
            <result column="tagsName" property="name"></result>
            <result column="color" property="color"></result>
            <result column="tid" property="residentId"></result>
        </collection>
    </resultMap>
<select id="selectPageList" resultType="com.vkl.basic.domain.vo.admin.BasicResidentListVo" resultMap="many"
            parameterType="com.vkl.basic.domain.bo.admin.BasicResidentAdminBo">
        select b.resident_id,b.`name`,b.sex,b.house_holder,b.resident_name,b.outsider,b.room,
        t.id as tagsId,t.`name` as tagsName,t.color,t.resident_id as tid
        from basic_resident b LEFT JOIN basic_resident_tags t
        on b.resident_id = t.resident_id
        where del_flg = '0'
        <if test="param.name != null and param.name != ''">
            and b.name like concat('%',#{param.name},'%')
            or
            b.resident_name like concat('%',#{param.name},'%')
        </if>
        <if test="param.tags != null and param.tags != ''">
            and t.name = #{param.tags}
        </if>
        order by b.resident_id
        limit #{query.pageNum},#{query.pageSize}
    </select>

正常查询tags有两条

加上分页条件,多的一端只有一条数据。

修改之后的sql

分页满足正常展示多的一端。

<!--一对多映射-->
    <resultMap id="many" type="com.vkl.basic.domain.vo.admin.BasicResidentListVo">
        <id property="residentId" column="resident_id"/>
        <result property="name" column="name"/>
        <result property="sex" column="sex"/>
        <result property="houseHolder" column="house_holder"/>
        <result property="residentName" column="resident_name"/>
        <result property="outsider" column="outsider"/>
        <result property="room" column="room"/>
        <collection property="tags" ofType="com.vkl.basic.domain.BasicResidentTags"
                    column="tid" select="selectTagsByResidentId">
        </collection>
    </resultMap>
    
    <!--主查询条件-->
    <select id="selectPageList" resultType="com.vkl.basic.domain.vo.admin.BasicResidentListVo" resultMap="many"
            parameterType="com.vkl.basic.domain.bo.admin.BasicResidentAdminBo">
        select b.resident_id,b.`name`,b.sex,b.house_holder,b.resident_name,b.outsider,b.room,
        t.id as tagsId,t.`name` as tagsName,t.color,t.resident_id as tid
        from basic_resident b LEFT JOIN basic_resident_tags t
        on b.resident_id = t.resident_id
        where del_flg = '0'
        <if test="param.name != null and param.name != ''">
            and b.name like concat('%',#{param.name},'%')
            or
            b.resident_name like concat('%',#{param.name},'%')
        </if>
        <if test="param.tags != null and param.tags != ''">
            and t.name = #{param.tags}
        </if>
        order by b.resident_id
        limit #{query.pageNum},#{query.pageSize}
    </select>
    
    <!--子查询-->
    <select id="selectTagsByResidentId" resultType="com.vkl.basic.domain.BasicResidentTags">
        select * from basic_resident_tags where resident_id=#{tid}
    </select>

总结

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

相关文章

  • Java实现企业微信消息推送功能的详细步骤

    Java实现企业微信消息推送功能的详细步骤

    这篇文章主要介绍了Java实现企业微信消息推送功能,本文图文实例代码相结合给大家介绍的非常详细,需要的朋友可以参考下
    2022-04-04
  • Java中上传图片压缩处理的方法示例

    Java中上传图片压缩处理的方法示例

    本篇文章主要介绍了Java中图片压缩处理的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • 浅谈Mybatis #和$区别以及原理

    浅谈Mybatis #和$区别以及原理

    这篇文章主要介绍了浅谈Mybatis #和$区别以及原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • Spring MVC接受表单自动封装特性实例解析

    Spring MVC接受表单自动封装特性实例解析

    这篇文章主要介绍了Spring MVC接受表单自动封装特性实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • idea克隆maven项目的方法步骤(图文)

    idea克隆maven项目的方法步骤(图文)

    这篇文章主要介绍了idea克隆maven项目的方法步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • JAVA实现较完善的布隆过滤器的示例代码

    JAVA实现较完善的布隆过滤器的示例代码

    这篇文章主要介绍了JAVA实现较完善的布隆过滤器的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-10-10
  • dubbo服务调用者的三种调用过程

    dubbo服务调用者的三种调用过程

    文章主要介绍了在Dubbo框架中进行服务调用的几种常见方法,包括使用注解、在XML中注册服务实例以及泛化调用
    2026-01-01
  • Spring配置文件如何使用${username}

    Spring配置文件如何使用${username}

    这篇文章主要介绍了Spring配置文件如何使用${username},文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • 详解 Java 中 equals 和 == 的区别

    详解 Java 中 equals 和 == 的区别

    这篇文章主要介绍了详解 Java 中 equals 和 == 的区别的相关资料,equals 和 == 都是用来检测两个字符串是否相等,返回值也都是布尔型,但是两者在内部比较的处理中却不尽相同需要的朋友可以参考下
    2017-03-03
  • 详解SpringBoot如何优雅的处理免登录接口

    详解SpringBoot如何优雅的处理免登录接口

    在项目开发过程中,会有很多API接口不需要登录就能直接访问,比如公开数据查询之类的,常规处理方法基本是 使用拦截器或过滤器,拦截需要认证的请求路径,本文介绍一个更优雅的方法自定义注解的方式,文中通过代码示例介绍的非常详细,需要的朋友可以参考下
    2024-01-01

最新评论