亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

MyBatisPlus 封裝分頁方法示例

 更新時間:2024年12月03日 10:36:20   作者:曹申陽  
本文主要介紹了基于MybatisPlus的分頁插件封裝,包括分頁結(jié)果對象、查詢對象的封裝,以及對象轉(zhuǎn)換處理,具有一定的參考價值,感興趣的可以了解一下

一、前言

作為一個 CRUD 工程師,查詢必然少不了,分頁查詢更是常見,市面上也有很多成熟的分頁插件,都各有優(yōu)缺點,這里整理一下,基于 MybatisPlus 的分頁插件進(jìn)一步封裝分頁的公共方法。

二、對象封裝

其實分頁插件已經(jīng)提供了很強大的功能,但是在業(yè)務(wù)開發(fā)的時候不夠精簡,返回了很多我們并不關(guān)注的數(shù)據(jù),在這個基礎(chǔ)上進(jìn)一步封裝,使其更貼合我們的業(yè)務(wù)開發(fā)。

2.1 分頁結(jié)果對象封裝

首先我們定義一個通用的分頁結(jié)果對象,PageVO 包含我們關(guān)注的主要幾個數(shù)據(jù)值,總條數(shù),總頁數(shù),數(shù)據(jù)集。這里為了兼容各種數(shù)據(jù)類型,這里的數(shù)據(jù)集的類型通過泛型指定

@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageVO<V> implements Serializable {
    private static final long serialVersionUID = 1L;

    @Schema(description = "總條數(shù)")
    private Long total;
    @Schema(description = "總頁數(shù)")
    private Long pages;
    @Schema(description = "數(shù)據(jù)")
    private List<V> records;

}

2.2 分頁查詢對象封裝

為了兼容查詢對象的不同類型,這里使用泛型定義查詢對象類型,后面我們只需要根據(jù)使用場景定義對應(yīng)的 Query 對象就可以了

@Data
public class PageQuery<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    @Schema(description = "當(dāng)前頁碼", defaultValue = "1")
    private Integer pageNum = 1;
    @Schema(description = "每頁顯示條數(shù)", defaultValue = "10")
    private Integer pageSize = 10;
    @Schema(description = "排序?qū)ο?,支持多字段排?)
    private List<OrderItem> orderItems;
    @Schema(description = "查詢對象")
    private T search;
}

2.3 結(jié)合 Query 對象使用案例

第一步:

比如我們現(xiàn)在要完成用戶列表的分頁查詢,那么首先我們需要定義對應(yīng)的查詢對象 **UserQuery, **這里簡單展示通過用戶名和昵稱進(jìn)行查詢。

@Data
public class UserQuery implements Serializable {
    private static final long serialVersionUID = 1L;

    @Schema(description = "用戶名")
    private String username;

    @Schema(description = "昵稱")
    private String nickname;
}

第二步:

定義我們返回時需要的結(jié)果對象,我這里就叫 **UserListVO **我習(xí)慣將列表的 **VO **對象命名為 **xxxListVO,**詳情對象命名為 xxxDetailVO

@Data
public class UserListVO implements Serializable {
    private static final long serialVersionUID = 1L;

    @Schema(description = "主鍵ID")
    private Long userId;

    @Schema(description = "用戶名")
    private String username;

    @Schema(description = "昵稱")
    private String nickname;

    @Schema(description = "創(chuàng)建時間")
    private LocalDateTime createTime;

    @Schema(description = "更新時間")
    private LocalDateTime updateTime;
}

第三步:

在 controller 層編寫接口

@Operation(summary = "分頁查詢")
@PostMapping("/page")
public R<PageVO<UserListVO>> findPage(@RequestBody PageQuery<UserQuery> userQuery) {
    PageVO<UserListVO> page = userService.findPage(userQuery);
    return R.ok(page);
}

可以看到這里我們通過前面定義的公共對象,以及具體的業(yè)務(wù)對象,經(jīng)過簡單的組裝完成了,請求參數(shù) **userQuery **以及返會結(jié)果的封裝,并且我們可以很清楚的知道對應(yīng)的類型,想要擴展也很容易實現(xiàn),以后所有的分頁查詢基本上都是類似的格式,不同的在于我們根據(jù)不同使用場景封裝對應(yīng)的業(yè)務(wù)返回 xxxVO 以及查詢對象 xxxQuery

第四步:

具體的分頁查詢實現(xiàn),即 findPage 方法的實現(xiàn)

@Override
public PageVO<UserListVO> findPage(PageQuery<UserQuery> userQuery) {
    // 將查詢對象 轉(zhuǎn)換為 Mybatis Plus 的 Page 對象
    Page<AdminUser> page = Page.of(userQuery.getPageNum(), userQuery.getPageSize());
    UserQuery search = userQuery.getSearch();
    // 查詢
    lambdaQuery()
        .eq(StrUtil.isNotBlank(search.getUsername()), AdminUser::getUsername, search.getUsername())
        .or()
        .like(StrUtil.isNotBlank(search.getNickname()), AdminUser::getNickname, search.getNickname())
        .page(page);
    // 將 Mybatis Plus 的 Page 對象 轉(zhuǎn)換為 PageVO
    List<AdminUser> records = page.getRecords();
    List<UserListVO> userListVOs = BeanUtil.copyToList(records, UserListVO.class);
    return new PageVO<>(page.getTotal(), page.getPages(), userListVOs);
}

測試一下

到這里基本上已經(jīng)完成了,但是細(xì)心的會發(fā)現(xiàn)我們沒有處理排序字段,而且這種對象來回轉(zhuǎn)換的方法非常繁瑣。

三、進(jìn)一步封裝對象轉(zhuǎn)換

對象轉(zhuǎn)換處理:

基于上面的接口實現(xiàn)進(jìn)一步完善,首先第一點,查詢對象 轉(zhuǎn)換為 Mybatis Plus 的 Page 對象,我們先來完成這個封裝。

你可以單獨寫到一個工具類里,這里我直接寫在 PageQuery 對象中,這里方便我拿取參數(shù),省的傳參了,而且這樣也更符合面向?qū)ο缶幊蹋@種轉(zhuǎn)換能力應(yīng)該屬于 PageQuery 對象。

/**
 * 將當(dāng)前對象轉(zhuǎn)換為 MybatisPlus 分頁對象
 *
 * @param <PO> PO類型
 * @return Page<PO>
 */
public <PO> Page<PO> toMpPage() {
    return Page.of(pageNum, pageSize);
}

那相同的 VO的轉(zhuǎn)換能力應(yīng)該由 PageVO提供,所以 VO轉(zhuǎn)換寫在 PageVO 里

/**
 * 將 MybatisPlus 分頁結(jié)果轉(zhuǎn)換為 PageDTO
 *
 * @param page        MybatisPlus 分頁結(jié)果
 * @param targetClass 目標(biāo)類型字節(jié)碼
 * @param <V>         目標(biāo)數(shù)據(jù)類型
 * @param <P>         原始數(shù)據(jù)類型
 * @return 分頁結(jié)果 PageDTO
 */
public static <V, P> PageVO<V> of(Page<P> page, Class<V> targetClass) {
    List<P> records = page.getRecords();
    if (records.isEmpty()) {
        return empty(page);
    }
    // 將原始數(shù)據(jù)轉(zhuǎn)換為目標(biāo)數(shù)據(jù) 這里我使用了 hutool 的 BeanUtil,可以根據(jù)需要自行替換
    List<V> vs = BeanUtil.copyToList(records, targetClass);
    return new PageVO<>(page.getTotal(), page.getPages(), vs);
}


/**
 * 返回空的分頁結(jié)果
 *
 * @param page MybatisPlus 分頁結(jié)果
 * @param <V>  目標(biāo)數(shù)據(jù)類型
 * @param <P>  原始數(shù)據(jù)類型
 * @return 分頁結(jié)果 PageDTO
 */
public static <V, P> PageVO<V> empty(Page<P> page) {
    return new PageVO<>(page.getPages(), page.getPages(), Collections.emptyList());
}

這樣我們之前的分頁查詢就可以寫成這樣

@Override
public PageVO<UserListVO> findPage(PageQuery<UserQuery> userQuery) {
    // 將查詢對象 轉(zhuǎn)換為 Mybatis Plus 的 Page 對象
    Page<AdminUser> page = userQuery.toMpPage();
    UserQuery search = userQuery.getSearch();
    // 查詢
    lambdaQuery()
        .eq(StrUtil.isNotBlank(search.getUsername()), AdminUser::getUsername, search.getUsername())
        .or()
        .like(StrUtil.isNotBlank(search.getNickname()), AdminUser::getNickname, search.getNickname())
        .page(page);
    // 將 Mybatis Plus 的 Page 對象 轉(zhuǎn)換為 PageVO
    return PageVO.of(page, UserListVO.class);
}

排序處理:

在我們處理將當(dāng)前對象轉(zhuǎn)換為 MybatisPlus分頁對象的時候,只處理了 pageNum 和 pageSize , 接下來我們處理一下排序的情況。

/**
 * 將當(dāng)前對象轉(zhuǎn)換為 MybatisPlus 分頁對象
 *
 * @param <PO> PO類型
 * @return Page<PO>
 */
public <PO> Page<PO> toMpPage() {
    Page<PO> page = Page.of(pageNum, pageSize);
    if (orderItems != null && !orderItems.isEmpty()) {
        page.addOrder(orderItems);
    } else {
        // 如果不傳默認(rèn)根據(jù)創(chuàng)建時間倒序
        page.addOrder(OrderItem.desc("create_time"));
    }
    return page;
}

測試一下

==> Preparing: SELECT user_id, username, password, nickname, create_time, update_time, is_deleted FROM itshare_admin_user WHERE is_deleted = 0 ORDER BY user_id DESC LIMIT ?

控制臺輸出的 SQL 也如我們預(yù)期一樣

多條件測試

==> Preparing: SELECT user_id, username, password, nickname, create_time, update_time, is_deleted FROM itshare_admin_user WHERE is_deleted = 0 ORDER BY user_id DESC, create_time ASC LIMIT ?

四、總結(jié)

這樣我們基本上完成了項目中分頁場景下的代碼封裝,后續(xù)分頁場景,我們只需要定義好 xxxQuery 對象,以及 xxxVO 對象即可完成分頁查詢,大大簡化了編碼過程,提高了編碼效率。其實就目前我們依然有很多具有共性的代碼,比如對條件 sql 的編寫,我們能不能根據(jù)對象類型以及前端配合傳參動態(tài)去實現(xiàn),這樣我們就可以完全解放雙手,定義兩個對象就搞定一個分頁接口的查詢了。

到此這篇關(guān)于MyBatisPlus 封裝分頁方法示例的文章就介紹到這了,更多相關(guān)MyBatisPlus 分頁內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • activemq整合springboot使用方法(個人微信小程序用)

    activemq整合springboot使用方法(個人微信小程序用)

    這篇文章主要介紹了activemq整合springboot使用(個人微信小程序用),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • MyBatis源碼剖析之Mapper代理方式詳解

    MyBatis源碼剖析之Mapper代理方式詳解

    這篇文章主要為大家詳細(xì)介紹了MyBatis中Mapper代理的方式,文中將通過源碼為大家進(jìn)行詳細(xì)的剖析,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-07-07
  • 淺談幾種Java自定義異常處理方式

    淺談幾種Java自定義異常處理方式

    在Java中,異常是一種常見的處理機制,本文主要介紹了淺談幾種Java自定義異常處理方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Maven工程路徑映射的實現(xiàn)示例

    Maven工程路徑映射的實現(xiàn)示例

    本文主要介紹了Maven工程路徑映射的實現(xiàn)示例,文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-04-04
  • Java?SpringBoot?獲取接口實現(xiàn)類匯總

    Java?SpringBoot?獲取接口實現(xiàn)類匯總

    這篇文章主要介紹了Java?SpringBoot?獲取接口實現(xiàn)類匯總,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • Java上傳文件錯誤java.lang.NoSuchMethodException的解決辦法

    Java上傳文件錯誤java.lang.NoSuchMethodException的解決辦法

    今天小編就為大家分享一篇關(guān)于Java上傳文件錯誤java.lang.NoSuchMethodException的解決辦法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Java 并發(fā)編程ArrayBlockingQueue的實現(xiàn)

    Java 并發(fā)編程ArrayBlockingQueue的實現(xiàn)

    這篇文章主要介紹了Java 并發(fā)編程ArrayBlockingQueue的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • 使用nexus3.X上傳本地jar包并且通過pom讀取的解決方案(全網(wǎng)最新)

    使用nexus3.X上傳本地jar包并且通過pom讀取的解決方案(全網(wǎng)最新)

    這篇文章主要介紹了使用nexus3.X上傳本地jar包并且通過pom讀取的解決方案(全網(wǎng)最新),本文內(nèi)容有點長,結(jié)合圖文實例給大家講解的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • spring中的BeanFactory與FactoryBean的講解

    spring中的BeanFactory與FactoryBean的講解

    今天小編就為大家分享一篇關(guān)于spring中的BeanFactory與FactoryBean的講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • java實現(xiàn)短地址服務(wù)的方法(附代碼)

    java實現(xiàn)短地址服務(wù)的方法(附代碼)

    大多數(shù)情況下URL太長,字符多,不便于發(fā)布復(fù)制和存儲,本文就介紹了通過java實現(xiàn)短地址服務(wù),減少了許多使用太長URL帶來的不便,需要的朋友可以參考下
    2015-07-07

最新評論