MyBatis中这么多的分页功能,你知道几个?

243 阅读4分钟

引言

         现在的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进行项目开发时,更好地理解和实现分页功能。如果有任何问题或需要进一步的讨论,请随时留言交流。