引言
现在的Web应用程序中,对数据进行条件查询并分页是一个最常见且常用的需求。对于使用MyBatis作为持久层框架的spring项目来讲,实现高效且灵活的分页功能尤为重要。
本文将探讨在MyBatis中实现分页的几种常见方法,并提供实际的代码示例,以帮助开发者在项目中快速、高效地实现分页功能。
请求与实现
- resquest
//其他一些查询条件
。。。
int current;
int size;
- response 这里我直接使用范型去操作
public class CommentVO<T> {
List<T> list;
/**
* 当前条数
*/
private Long size;
/**
* 每页条数
*/
private Long pageSize;
/**
* 总条数
*/
private Long total;
/**
* 总页数
*/
private Long pages;
如果查询到的内容我们就可以直接set入list中,如果有需要的参数我们可以copy到这个返回类中
分页实现
首先分页在数据库中体现在在关键字limit的两个参数中即当前条数以及每页几条数据,如果面对于最简单的前端分页需求,只需要这两个参数那么我们在后端就可以直接进行手动分页,实现如下:
手动分页
只要将前端传递这两个参数拼接即可
public interface UserMapper {
List<User> selectByPage(@Param("current") int current, @Param("size") int size);
}
对应的xml
<select id="selectByPage" resultType="User">
SELECT * FROM user LIMIT #{current}, #{size}
</select>
这样只要将我们数据给前端拼接过去就可以了
但是有些时候在前端渲染的时候还需要返回总页数,用于渲染下标等这些操作。
如果我们还使用上面的手动分页就需要我们去请求两次数据库(第一次去根据条件查询总共几条,第二次去按照分页条件去查询返回对应的list),而且还会造成xml中的大量代码冗余
MyBatis-plus分页
如果我们选择使用myabtis-plus那么我们就只需要去引入相关的依赖与配置即可解决这种问题
- 引入依赖
<!-- 在 pom.xml 中 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
- 引入配置类
@Configuration public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(); // 设置当前页和每页显示条数的最大限制,这里假设不超过1000条
paginationInnerInterceptor.setMaxLimit(1000L);
interceptor.addInnerInterceptor(paginationInnerInterceptor);
return interceptor;
}
}
- 代码实现
public Page<User> getUserListByPage(Integer current, Integer size) {
Page<User> page = new Page<>(current, size);
//后面的null是wrapper条件,如果为空就代表获取全部数据
return userMapper.selectPage(page, null);
}
PageHelper
上面的写法对于一些简单的分页可以使用上面那种方式去实现,但是我们要写一些复杂的分页,要将分页写入到xml中我们就需要去使用一些插件进行,就比如这个pageHelper
- 引入依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>最新版本</version>
</dependency>
- 配置yml指定数据库,对其进行拦截分页
##pageHelper分页插件配置
pagehelper:
##方言配置为mysql数据库
helper-dialect: mysql
- 代码实现
public PageInfo<SchoolStudent> getPage(Integer current, Integer size) {
PageHelper.startPage(current, size);
List<SchoolStudent> list = this.list();
//用PageInfo对结果进行包装
PageInfo page = new PageInfo(list);
CommentVO pageVo = new CommentVO();
pageVo.setlist(list);
//返回一些必要的参数
BeanUtils.copyProperties(pageVo,page);
return page;
}
selectPage
这个工具不需要去引用包,但是需要引入工具类如下:
@Data
@NoArgsConstructor
public class ExamPaginationInnerInterceptor extends PaginationInnerInterceptor {
/**
* 数据库类型
* <p>
* 查看 {@link #findIDialect(Executor)} 逻辑
*/
private DbType dbType;
/**
* 方言实现类
* <p>
* 查看 {@link #findIDialect(Executor)} 逻辑
*/
private IDialect dialect;
public ExamPaginationInnerInterceptor(DbType dbType) {
this.dbType = dbType;
}
public ExamPaginationInnerInterceptor(IDialect dialect) {
this.dialect = dialect;
}
@Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds,
ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
IPage<?> page = ParameterUtils.findPage(parameter).orElse(null);
// size 小于 0 直接设置为 0 , 即不查询任何数据
if (null != page && page.getSize() < 0) {
page.setSize(0);
}
super.beforeQuery(executor, ms, page, rowBounds, resultHandler, boundSql);
}
}
- 然后我们只需要在传入的地方进行拼接
IPage<List<UserVO>> getList(@Param("page") Page page,
@Param("dto") InvoceSellerDTO invoceSellerDTO);
在xml中就不需要再limt实现即可实现功能
小结
分页是数据密集型应用的关键组成部分。在MyBatis中,我们可以通过手动分页、使用分页插件以及选择合适的分页方式来实现这一功能。选择哪种方法取决于具体的应用场景和性能要求。正确地实现分页不仅可以提升应用的性能,还能提升用户体验。
希望本文能够帮助你在使用MyBatis进行项目开发时,更好地理解和实现分页功能。如果有任何问题或需要进一步的讨论,请随时留言交流。