溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Mybatisplus分頁(yè)查詢不生效如何排查

發(fā)布時(shí)間:2023-03-15 14:15:54 來(lái)源:億速云 閱讀:131 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要介紹“Mybatisplus分頁(yè)查詢不生效如何排查”的相關(guān)知識(shí),小編通過(guò)實(shí)際案例向大家展示操作過(guò)程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“Mybatisplus分頁(yè)查詢不生效如何排查”文章能幫助大家解決問(wèn)題。

一、問(wèn)題描述

在查詢的時(shí)候,發(fā)現(xiàn)點(diǎn)擊后臺(tái)的分頁(yè)器數(shù)字,第2頁(yè)時(shí)候,數(shù)據(jù)還是和第1頁(yè)的一致。就看后臺(tái)的數(shù)據(jù)庫(kù)打印語(yǔ)句,如下所示。點(diǎn)擊第一頁(yè)和第二頁(yè)都是這個(gè),limit后的參數(shù)只有一個(gè),前期做過(guò)類似,點(diǎn)擊第二頁(yè)分頁(yè)的時(shí)候,語(yǔ)句是LIMIT ?,?

ON ap.id = a.project_id ORDER BY a.create_time DESC LIMIT ?

二、分析步驟

1.首先開(kāi)始懷疑的是自己的分頁(yè)對(duì)象出現(xiàn)了問(wèn)題,因?yàn)?a title="MySQL" target="_blank" href="http://www.kemok4.com/mysql/">MySQL ORM框架使用了JPA框架遺留的代碼。將spring-data的分頁(yè)對(duì)象org.springframework.data.domain.Pageable轉(zhuǎn)成了mybatis-plus的分頁(yè)對(duì)象com.baomidou.mybatisplus.extension.plugins.pagination.Page<T>。

debug后,Page<T>的 current 和 size 都是存在且對(duì)應(yīng)前臺(tái)傳來(lái)的值。

2.接著懷疑是mybatis-plus的攔截器順序問(wèn)題,因?yàn)轫?xiàng)目里寫(xiě)了數(shù)據(jù)權(quán)限的攔截器,在研究數(shù)據(jù)權(quán)限攔截器的時(shí)候就看到有說(shuō)攔截器添加順序會(huì)影響到SQL語(yǔ)句拼接的正確性。對(duì)比了正常的添加順序后,這部分也沒(méi)有問(wèn)題。

   @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

        //添加數(shù)據(jù)權(quán)限處理器,注意順序,先數(shù)據(jù)權(quán)限再分頁(yè)
        MyDataPermissionInterceptor dataPermissionInterceptor = new MyDataPermissionInterceptor();
        // 添加自定義的數(shù)據(jù)權(quán)限處理器
        dataPermissionInterceptor.setDataPermissionHandler(new MyDataPermissionHandler());
        interceptor.addInnerInterceptor(dataPermissionInterceptor);

        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }

3.發(fā)現(xiàn)這兩部分都沒(méi)問(wèn)題后,決定還是debug一下分頁(yè)攔截器。

重要的分頁(yè)SQL語(yǔ)句拼接函數(shù)如下。

DialectModel model = dialect.buildPaginationSql(buildSql, page.offset(), page.getSize());

進(jìn)入到里面,這里數(shù)據(jù)庫(kù)使用的MySQL。

public class MySqlDialect implements IDialect {

    @Override
    public DialectModel buildPaginationSql(String originalSql, long offset, long limit) {
        StringBuilder sql = new StringBuilder(originalSql).append(" LIMIT ").append(FIRST_MARK);
        if (offset != 0L) {
            sql.append(StringPool.COMMA).append(SECOND_MARK);
            return new DialectModel(sql.toString(), offset, limit).setConsumerChain();
        } else {
            return new DialectModel(sql.toString(), limit).setConsumer(true);
        }
    }
}

可以看到偏移量offset至關(guān)重要,決定了拼接的條件判斷。

又發(fā)現(xiàn),offet的值和current相關(guān),根據(jù)排查結(jié)果來(lái)看,current 是正常傳值的。

default long offset() {
        long current = this.getCurrent();
        return current <= 1L ? 0L : Math.max((current - 1L) * this.getSize(), 0L);
    }

因此到這里我們就會(huì)發(fā)現(xiàn),是offset的真實(shí)值不正確。

當(dāng)后臺(tái)前端頁(yè)面?zhèn)鱽?lái)的current0時(shí),offset等于0

當(dāng)后臺(tái)前端頁(yè)面?zhèn)鱽?lái)的current1時(shí),offset依舊等于0

而回到拼接函數(shù)buildPaginationSql中,不等于0的時(shí)候才會(huì)有 兩個(gè)參數(shù)的拼接。

至此,這個(gè)問(wèn)題解決了,就是在對(duì)象轉(zhuǎn)換時(shí),沒(méi)有對(duì)current的值進(jìn)行 + 1

三、解決方案

public class MyPage<T> extends Page<T> {

    /**
     * @Description: 將spring的分頁(yè)對(duì)象轉(zhuǎn)成Mybatis
     * @param pageable:
     * @return: null
     **/
    public MyPage(Pageable pageable) {
        this.setSize(pageable.getPageSize());
        this.setCurrent(pageable.getPageNumber() + 1);
    }
}

關(guān)于“Mybatisplus分頁(yè)查詢不生效如何排查”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI