如何实现后端开发框架(四)-分页查询
1. 问题描述
后端查询数据库都少不了分页查询功能,那么如何在框架层面上实现一个通用的分页查询功能,让开发人员方便的使用呢?
2. 实现思路
内部使用Mybatis-Plus的分页插件,外部需要封装一下便于开发人员使用。
3. 实现步骤
3.1 添加分页插件
添加Mybatis-Plus分页插件,实现分页相关功能。
@Configuration
public class MybatisPlusConfig {
/** 添加分页插件 */
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 如果配置多个插件, 切记分页最后添加
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbType
return interceptor;
}
}
3.2 添加分页查询参数
分页查询时都需要设置2个参数:当前页号(currentPage)和每页显示记录数量(pageSize),将这两个参数放入实体基类中,这样后端接收的传参对象和返回的结果对象都可以用同一个实体类。
@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内置的分页对象是Page,但为了框架以后的扩展性还是要使用自定义分页对象MyPage封装下,同时将Page的当前页号(current)和每页显示记录数量(size)用MyPage的currentPage和pageSize属性替换下。
/** 自定义分页类,序列化时需要去掉mybatis-plus Page类上的原生size和current字段 */
@JsonIgnoreProperties({"size", "current"})
public class MyPage<T> extends Page<T> {
/** 每页显示记录数量 */
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 实现自己的分页方法
在Service基类上实现通用的分页方法,这样便于开发人员使用。
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> {
/**
* 根据条件查询所有记录
*
* @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;
}
/**
* 根据条件分页查询记录
*
* @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子项目:
https://github.com/randy0098/framework-samples