• mybatisplus 自定义mapper加多表联查结合分页插件查询时出现缺失数据的问题


    问题描述

    最近做项目时使用了mybatisplus,分页插件也使用的是mybatisplus自带的分页插件,业务需求是查询客户列表,每个客户列表中有一个子列表,在通过分页插件查询后,会出现数量总数为子列表总数、客户列表与子列表不对等。

    1、配置mybatis-plus插件

    @Configuration
    @MapperScan("com.guigu.mapper") //可以将启动类中的注解移到此处
    public class MybatisPlusConfig {
        /**
         *
         * 1 怎么来配置mybatis-plus中的插件?
         *   这里所需要的类型是MybatisPlusInterceptor,这是mybatis-plus的一个拦截器,用于配置mybatis-plus中的插件。
         * 2 为什么要使用拦截器MybatisPlusInterceptor呢?
         *    这里边的原理和mybatis分页插件的功能是一样的,工作流程如下 :
         *   (1)第一步:执行查询功能。
         *   (2)第二步:拦截器对查询功能进行拦截。
         *   (3)第三步:拦截器对查询功能的基础上做了额外的处理,达到分页的效果(功能)。
         * 3 对比配置mybatis中的插件?
         *   用的也是拦截器的方式。
         *
         * @return MybatisPlusInterceptor
         */
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            //添加:分页插件
            //参数:new PaginationInnerInterceptor(DbType.MYSQL),是专门为mysql定制实现的内部的分页插件
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
            return interceptor;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    2、mapper语句

     需求:根据年龄查询用户列表,分页显示
         *
         * 第一步:xml自定义分页,Mapper接口方法
         *1步:如果想要mybatis-plus的分布插件来作用于我们自定义的sql语句的话,
         * 		第一个参数必须得是一个分页对象:@Param("page") Page<User> page。
         * 第二步:因为Mapper接口方法有2个参数的话
         *       方案1:使用mybatis提供的访问方式
         *       方案2:也可以使用@param来设置命名参数,来规定参数的访问规则
        Page<CustomerEntity> queryCustomerList(@Param("page") Page<CustomerEntity> customerPage,
                                               @Param("customerName") String customerName,
                                               @Param("deptIds") List<Long> deptIds,
                                               @Param("userIds") List<Long> userIds,
                                               @Param("delFlag") Integer logicNotDeleteValue)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
        <resultMap id="customerList" type="customerEntity">
            <id property="customerId" column="customer_id"/>
            <result property="customerName" column="customer_name"/>
            <collection property="children" select="queryList" column="customer_id" ofType="customerInfoEntity">
            collection>
            <collection property="children" ofType="customerInfoEntity">
                <id property="customerInfoId" column="customer_info_id"/>
                <result property="customerId" column="customer_id"/>
                <result property="deptId" column="dept_id"/>
                <result property="industry" column="industry"/>
                <result property="level" column="level"/>
                <result property="source" column="source"/>
                <result property="highSeas" column="high_seas"/>
                <result property="remark" column="remark"/>
                <result property="crtTime" column="crt_time"/>
                <result property="crtName" column="crt_name"/>
                <result property="crtUserId" column="crt_user_id"/>
            collection>
        resultMap>
        <select id="queryCustomerList" resultMap="customerList">
            SELECT
            c.customer_id,
            c.customer_name,
            ci.customer_info_id,
            ci.customer_id,
            ci.dept_id,
            ci.industry,
            ci.level,
            ci.source,
            ci.high_seas,
            ci.remark,
            ci.crt_time,
            ci.crt_name,
            ci.crt_user_id
            FROM customer c
            JOIN customer_info ci on c.customer_id = ci.customer_id
            where ci.high_seas = 0
            and ci.del_flag = #{delFlag}
            and c.del_flag =#{delFlag}
            <if test="customerName != null">
                AND c.customer_name like concat('%',#{customerName},'%')
            if>
            <if test="deptIds.size>0">
                AND ci.dept_id in
                <foreach collection="deptIds" item="id" separator="," open="(" close=")">
                    #{id}
                foreach>
            if>
            <if test="userIds.size>0">
                AND ci.crt_user_id in
                <foreach collection="userIds" item="id" separator="," open="(" close=")">
                    #{id}
                foreach>
            if>
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    上述语句查询的结果数是表customer_info的数量而不是表customer的数量,客户列表下有多个子列表时会分成多个相同的客户。

    解决办法

    那我们怎么才能查到正确得一对多的分页结果呢?mybatis提供另一种方式,使用mybatis的子查询映射。

    	<resultMap id="customerList" type="customerEntity">
            <id property="customerId" column="customer_id"/>
            <result property="customerName" column="customer_name"/>
            <collection property="children" select="queryList" column="customer_id" ofType="customerInfoEntity">
            </collection>
        </resultMap>
    
        <select id="queryList" resultType="customerInfoEntity">
            select ci.customer_info_id,
                   ci.customer_id,
                   ci.dept_id,
                   ci.industry,
                   ci.level,
                   ci.source,
                   ci.high_seas,
                   ci.remark,
                   ci.crt_time,
                   ci.crt_name,
                   ci.crt_user_id
            from customer_info ci
            where ci.customer_id = #{customer_id};
        </select>
    
        <!--    查询未加入公海池的客户列表-->
        <select id="queryCustomerList" resultMap="customerList">
            SELECT
            c.customer_id,
            c.customer_name,
            ci.customer_info_id,
            ci.customer_id,
            ci.dept_id,
            ci.industry,
            ci.level,
            ci.source,
            ci.high_seas,
            ci.remark,
            ci.crt_time,
            ci.crt_name,
            ci.crt_user_id
            FROM customer c
            JOIN customer_info ci on c.customer_id = ci.customer_id
            where ci.high_seas = 0
            and ci.del_flag = #{delFlag}
            and c.del_flag =#{delFlag}
            <if test="customerName != null">
                AND c.customer_name like concat('%',#{customerName},'%')
            </if>
            <if test="deptIds.size>0">
                AND ci.dept_id in
                <foreach collection="deptIds" item="id" separator="," open="(" close=")">
                    #{id}
                </foreach>
            </if>
            <if test="userIds.size>0">
                AND ci.crt_user_id in
                <foreach collection="userIds" item="id" separator="," open="(" close=")">
                    #{id}
                </foreach>
            </if>
        </select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    注意: collection中的colum属性需要填两表关联的字段,也就是customer_id

  • 相关阅读:
    URL跳转漏洞
    Fleet公测啦!真的轻量?
    前端性能优化
    系统性学习vue-vue3
    【树状数组该回炉重造了】Codeforces Round #813 (Div. 2) E2. LCM Sum (hard version)
    DBCO-PEG-sulfadimethoxine 二苯并环辛炔-聚乙二醇-磺胺地索辛 DBCO-PEG-磺胺地索辛
    自然语言处理NLP:一文了解NLP自然语言处理技术,NLP在生活中的应用,图导加深了解,NLP语料库,NLP开源工具
    HDLBits: 在线学习 SystemVerilog(三)-Problem 10-14
    Maven系列第3篇:详解maven解决依赖问题
    关于 ELEMENTOR 的常见问题
  • 原文地址:https://blog.csdn.net/xieyfjejwaj/article/details/133868658