ruoyi分頁問題

氣死了

氣得我直接剛剛解決這個(gè)問題,就馬上來寫這篇文章了

這樣也好,我能把整個(gè)過程完整記錄下來

那開始吧

過程

最近在做畢設(shè)嘛,用的是RuoYi-Vue,用起來真的非常方便,極大的提高了開發(fā)效率。做起畢設(shè)或其他小項(xiàng)目真的非常容易,尤其加上它的代碼生成工具,非常方便。而且我不光是在用,同時(shí)其實(shí)也是在學(xué)習(xí),從中還是能學(xué)到很多東西的。

還有一個(gè)感觸就是對于長期被業(yè)務(wù)折騰到半死,對代碼失去信心的程序員,他們看到這樣的開源項(xiàng)目,我相信他們肯定是開心,因?yàn)檫@種開源項(xiàng)目代碼風(fēng)格上很統(tǒng)一、規(guī)范標(biāo)準(zhǔn)執(zhí)行的很到位,看起來真的賞心悅目。

問題簡述

好了,回到正題!

今天做畢設(shè),造數(shù)據(jù)測試的時(shí)候,發(fā)現(xiàn)分頁功能失效了,前端調(diào)用后端分頁接口返回的total有問題

{total: 10,…}
    code: 200
    msg: "查詢成功"
    rows: [{searchValue: null, createBy: null, createTime: "2022-03-18 20:36:55", updateBy: null,…},…]
    total: 10

total總是返回當(dāng)前數(shù)據(jù)的size

我很是不解,自認(rèn)為對于ruoyi分頁流程很是熟悉,對照官網(wǎng)找問題,愣是找了半天沒發(fā)現(xiàn)問題

官網(wǎng):后臺手冊 | RuoYi

檢查了半天沒發(fā)現(xiàn)什么問題,只好先去找找有沒有遇到同樣問題的,果然,有不少

看完后,大致明白是怎么回事,這其實(shí)是PageHelper的問題

梳理流程

按照ruoyi的流程理一遍

1、后端分頁接口SysUserController extends BaseController

/**
* 獲取用戶列表
*/
@PreAuthorize("@ss.hasPermi('system:user:list')")
@GetMapping("/list")
public TableDataInfo list(SysUser user) {
    // 開啟分頁,要緊接著分頁(service/mapper),這里ruoyi進(jìn)行了封裝
    startPage();
    List<SysUser> list = userService.selectUserList(user);
    return getDataTable(list);
}

點(diǎn)開startPage();,這是父類BaseController的方法

protected void startPage() {
    // 獲取request中關(guān)于分頁的請求,具體有關(guān)于一個(gè)ServletUtils的類,可以自行了解
    PageDomain pageDomain = TableSupport.buildPageRequest();
    Integer pageNum = pageDomain.getPageNum();
    Integer pageSize = pageDomain.getPageSize();
    if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) {
        String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
        Boolean reasonable = pageDomain.getReasonable();
        // 真正的開始分頁
        PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
    }
}

2、來到SysUserServiceImpl

/**
 * 根據(jù)條件分頁查詢用戶列表
 *
 * @param user 用戶信息
 * @return 用戶信息集合信息
 */
@Override
@DataScope(deptAlias = "d", userAlias = "u")
public List<SysUser> selectUserList(SysUser user) {
    return userMapper.selectUserList(user);
}

發(fā)現(xiàn)這里的service就一行?

PageHelper就是在這發(fā)揮了作用,進(jìn)行了分頁

其實(shí)我的問題就在這里,不過我要先把后面的流程走完

3、查到數(shù)據(jù)我們回到SysUserController,這次關(guān)注他的return getDataTable(list);

/**
 * 響應(yīng)請求分頁數(shù)據(jù)
 */
@SuppressWarnings({"rawtypes", "unchecked"})
protected TableDataInfo getDataTable(List<?> list) {
    TableDataInfo rspData = new TableDataInfo();
    rspData.setCode(HttpStatus.SUCCESS);
    rspData.setMsg("查詢成功");
    rspData.setRows(list);
    rspData.setTotal(new PageInfo(list).getTotal());
    return rspData;
}

這就是最終的相應(yīng)結(jié)果,既然是total出問題,那就重點(diǎn)關(guān)注setTotal方法,直接點(diǎn)進(jìn)new PageInfo(list).getTotal()

public PageInfo(List<T> list) {
    this(list, 8);
}

public PageInfo(List<T> list, int navigatePages) {
    super(list);
    this.isFirstPage = false;
    this.isLastPage = false;
    this.hasPreviousPage = false;
    this.hasNextPage = false;
    if (list instanceof Page) {
        Page page = (Page)list;
        this.pageNum = page.getPageNum();
        this.pageSize = page.getPageSize();
        this.pages = page.getPages();
        this.size = page.size();
        if (this.size == 0) {
            this.startRow = 0L;
            this.endRow = 0L;
        } else {
            this.startRow = page.getStartRow() + 1L;
            this.endRow = this.startRow - 1L + (long)this.size;
        }
    } else if (list instanceof Collection) {
        this.pageNum = 1;
        this.pageSize = list.size();
        this.pages = this.pageSize > 0 ? 1 : 0;
        this.size = list.size();
        this.startRow = 0L;
        this.endRow = list.size() > 0 ? (long)(list.size() - 1) : 0L;
    }

    if (list instanceof Collection) {
        this.calcByNavigatePages(navigatePages);
    }

}

最終調(diào)用的是下面的構(gòu)造方法,那么就進(jìn)到super(list);

public PageSerializable(List<T> list) {
    this.list = list;
    // 是否是Page對象
    if (list instanceof Page) {
        this.total = ((Page)list).getTotal();
    } else {
        this.total = (long)list.size();
    }

}

這是com.github.pagehelper包下的,就是在這里為PageInfo設(shè)置了total,當(dāng)然也是為我們最終相應(yīng)設(shè)置了

???

Page哪里來的

4、Page

package com.github.pagehelper;

public class Page<E> extends ArrayList<E> implements Closeable {
    ...
}

從這里可以看出Page繼承了ArrayList也是就實(shí)現(xiàn)了List

debug結(jié)果如下,發(fā)現(xiàn)在執(zhí)行完service代碼后,PageHelper就已經(jīng)完成這一步,那么自然就設(shè)置好了total

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-tcoj9Laf-1648217426077)(https://cdn.jsdelivr.net/gh/wnhyang/clouding@master/cloud-picture/image.2n0r5fmnpj80.webp)]

上面是正常流程梳理,接下看我的代碼,哪里出了問題,導(dǎo)致total總是錯(cuò)的

問題與解決

上面是舉得ruoyi原本的例子,因?yàn)槲覜]有改動(dòng),所以也就沒有問題

在我的模塊上,我其他的代碼實(shí)現(xiàn)也相同,就是在service上又處理了一次

/**
 * 查詢?nèi)蝿?wù)列表
 *
 * @param task 任務(wù)
 * @return 任務(wù)
 */
@Override
public List<Task> selectTaskList(Task task) {
    return taskMapper.selectTaskList(task).stream().map(this::fill).collect(Collectors.toList());
}

這里的fill就是又一個(gè)填充數(shù)據(jù)的流程

打印sql日志沒有問題,是有分頁流程的(查總數(shù),然后limit

debug發(fā)現(xiàn)這里list變成了,并非Page,也就把total設(shè)置為list.size()

[圖片上傳失敗...(image-fca05e-1677945618204)]

其實(shí)問題早就在查到資料后發(fā)現(xiàn)了,但是大多數(shù)處理方法我都看不上,什么再調(diào)用PageHelper.startPage,轉(zhuǎn)換成PageInfo之類的,都會(huì)讓我懷疑我是否有必要用了

尤其是在已經(jīng)使用了ruoyi之后,重新在service做那簡直太麻煩了,因?yàn)槟菢游疫€需要把ruoyi封裝在Controller上的一些東西拿過去,折騰不了

最后,找到一種非常簡單的方法解決了

就是,看上面的代碼其是又調(diào)用了stream的轉(zhuǎn)換流程的,可能就是在這里PageHelper出現(xiàn)了問題

那么試著將fill方法變成void,反正也是填充數(shù)據(jù),沒有影響的,改動(dòng)后如下

@Override
public List<Task> selectTaskList(Task task) {
    List<Task> taskList = taskMapper.selectTaskList(task);
    taskList.forEach(this::fill);
    return taskList;
}

這次debug就是Page對象了,一切都正常了

總結(jié)

如果你成功帶入我的節(jié)奏,那很好,你認(rèn)真看了;如果你發(fā)現(xiàn)其中問題了,那更好了,歡迎指正;如果你還能發(fā)現(xiàn)我另一個(gè)想討論的問題,那我更開心了

我想討論的就藏在

發(fā)現(xiàn)這里的service就一行?

這句話里了

很奇怪我們的業(yè)務(wù)邏輯代碼不都是幾十行,上百行的嗎???

為什么service就一行mapper?

篇幅問題,一下在討論吧?。?!??

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容