如何實現(xiàn)后端開發(fā)框架(四)-分頁查詢
1. 問題描述
后端查詢數(shù)據(jù)庫都少不了分頁查詢功能晴竞,那么如何在框架層面上實現(xiàn)一個通用的分頁查詢功能,讓開發(fā)人員方便的使用呢颓鲜?
2. 實現(xiàn)思路
內(nèi)部使用Mybatis-Plus的分頁插件典予,外部需要封裝一下便于開發(fā)人員使用甜滨。
3. 實現(xiàn)步驟
3.1 添加分頁插件
添加Mybatis-Plus分頁插件瘤袖,實現(xiàn)分頁相關功能衣摩。
@Configuration
public class MybatisPlusConfig {
/** 添加分頁插件 */
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 如果配置多個插件, 切記分頁最后添加
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 如果有多數(shù)據(jù)源可以不配具體類型, 否則都建議配上具體的 DbType
return interceptor;
}
}
3.2 添加分頁查詢參數(shù)
分頁查詢時都需要設置2個參數(shù):當前頁號(currentPage)和每頁顯示記錄數(shù)量(pageSize),將這兩個參數(shù)放入實體基類中捂敌,這樣后端接收的傳參對象和返回的結果對象都可以用同一個實體類艾扮。
@Data
@EqualsAndHashCode()
public class MyBaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "ID")
protected String id;
@TableField(exist = false)
protected long pageSize;
@TableField(exist = false)
protected long currentPage;
}
3.3 自定義分頁對象
Mybatis-Plus內(nèi)置的分頁對象是Page,但為了框架以后的擴展性還是要使用自定義分頁對象MyPage封裝下占婉,同時將Page的當前頁號(current)和每頁顯示記錄數(shù)量(size)用MyPage的currentPage和pageSize屬性替換下泡嘴。
/** 自定義分頁類,序列化時需要去掉mybatis-plus Page類上的原生size和current字段 */
@JsonIgnoreProperties({"size", "current"})
public class MyPage<T> extends Page<T> {
/** 每頁顯示記錄數(shù)量 */
protected long pageSize;
/** 當前頁號 */
protected long currentPage;
public MyPage() {}
public MyPage(long currentPage, long pageSize) {
super(currentPage, pageSize);
this.currentPage = currentPage;
this.pageSize = pageSize;
}
public MyPage(long currentPage, long pageSize, long total) {
super(currentPage, pageSize, total);
this.currentPage = currentPage;
this.pageSize = pageSize;
}
public MyPage(long currentPage, long pageSize, boolean isSearchCount) {
super(currentPage, pageSize, isSearchCount);
this.currentPage = currentPage;
this.pageSize = pageSize;
}
public MyPage(long currentPage, long pageSize, long total, boolean isSearchCount) {
super(currentPage, pageSize, total, isSearchCount);
this.currentPage = currentPage;
this.pageSize = pageSize;
}
public long getPageSize() {
return pageSize;
}
public void setPageSize(long pageSize) {
this.pageSize = pageSize;
this.size = pageSize;
}
public long getCurrentPage() {
return currentPage;
}
public void setCurrentPage(long currentPage) {
this.currentPage = currentPage;
this.current = currentPage;
}
}
3.4 實現(xiàn)自己的分頁方法
在Service基類上實現(xiàn)通用的分頁方法逆济,這樣便于開發(fā)人員使用酌予。
public interface MyBaseService<T> extends IService<T> {
default MyPage myPage(MyPage page, Wrapper<T> queryWrapper) {
MyPage myPage = getBaseMapper().selectPage(page, queryWrapper);
myPage.setCurrentPage(myPage.getCurrent());
myPage.setPageSize(myPage.getSize());
return myPage;
}
}
4. 測試代碼
@RestController
@RequestMapping("/test/user")
public class UserController extends MyBaseController<UserService, User> {
/**
* 根據(jù)條件查詢所有記錄
*
* @param user
* @return
*/
@RequestMapping(value = "/list", method = RequestMethod.POST)
public List<User> list(@RequestBody(required = false) User user) {
List<User> result = myBaseService.list(new QueryWrapper(user));
return result;
}
/**
* 根據(jù)條件分頁查詢記錄
*
* @param user
* @return
*/
@RequestMapping(value = "/pageList", method = RequestMethod.POST)
public MyPage<User> pageList(@RequestBody User user) {
MyPage<User> page = new MyPage<>(user.getCurrentPage(), user.getPageSize());
MyPage<User> result = myBaseService.myPage(page, new QueryWrapper(user));
return result;
}
}
5. 完整代碼
完整代碼見以下Git倉庫中的page-list子項目: