mybatis plus size=0时,重写PaginationInnerInterceptor,查询全部数据且total有值

针对Mybatis-Plus分页查询接口在特殊场景下无法同时返回全部数据和正确total值的问题,博主通过自定义分页拦截器解决了这一矛盾。在拦截器中,当size为0时,将total值设为size,从而在获取所有数据的同时确保total的准确性。此解决方案涉及数据库查询优化和Mybatis-Plus拦截器的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、遇到问题:

        分页查询接口,在特殊场景下,要求不分页,返回全部数据。mp默认当size=-1时,会返回全部数据,但是total为0;当size=0时,total有值,但是没数据。没法在返回全部数据的同时,total也有值。

2、解决方法:

        自定义分页拦截器,重写拦截器中的handlerLimit方法,巧妙规避当size=0,total有值list无值问题

// 自定义分页拦截器
public class CustomPaginationInnerInterceptor extends PaginationInnerInterceptor {
    public CustomPaginationInnerInterceptor(DbType dbType) {
        super(dbType);
    }

    @Override
    protected void handlerLimit(IPage<?> page) {
        // 此时,mp已完成对total的查询,将total设置成size值,完成对数据的查询
        final long size = page.getSize();
        if (size == 0) {
            page.setSize(page.getTotal());
        }
        super.handlerLimit(page);
    }
}
// mybatis-plus分页插件
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        CustomPaginationInnerInterceptor pageInterceptor = new CustomPaginationInnerInterceptor(DbType.POSTGRE_SQL);
        pageInterceptor.setOverflow(true);
        interceptor.addInnerInterceptor(pageInterceptor);
        return interceptor;
    }
}

<think>我们正在讨论MyBatisPlus中的SelectPage方法。根据用户之前的问题,他要求一个关于MyBatisPlus中SelectPage的用法示例或解决方案。注意,之前的回答中提到了SQL分页的多种方式,但现在用户特别询问MyBatisPlus框架中的SelectPage。MyBatisPlus是一个MyBatis的增强工具,提供了很多便捷的功能,其中就包括分页插件。在MyBatisPlus中,分页查询可以通过内置的Page对象和SelectPage方法来实现。以下是一个使用MyBatisPlus进行分页查询的步骤和示例:###1.配置分页插件首先,我们需要在SpringBoot的配置类中配置MyBatisPlus分页插件。例如:```java@ConfigurationpublicclassMybatisPlusConfig{@BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(){MybatisPlusInterceptorinterceptor=newMybatisPlusInterceptor();//添加分页插件interceptor.addInnerInterceptor(newPaginationInnerInterceptor(DbType.MYSQL));returninterceptor;}}```###2.创建分页对象在Service或Controller中,我们可以创建一个分页对象(Page),并指定当前页和每页大小。###3.使用SelectPage方法然后,使用MyBatisPlus的Service或Mapper的selectPage方法进行分页查询。###示例代码假设我们有一个User实体类和对应的Mapper(UserMapper)以及Service(UserService)。**Controller层示例:**```java@RestController@RequestMapping("/user")publicclassUserController{@AutowiredprivateUserServiceuserService;@GetMapping("/page")publicR<Page<User>>page(@RequestParam(defaultValue="1")intpageNo,@RequestParam(defaultValue="10")intpageSize){//创建分页对象Page<User>page=newPage<>(pageNo,pageSize);//调用分页查询方法Page<User>userPage=userService.page(page,null);returnR.ok(userPage);}}```**Service层接口:**```javapublicinterfaceUserServiceextendsIService<User>{//继承IService接口,已经内置了page方法}```**Service实现类:**```java@ServicepublicclassUserServiceImplextendsServiceImpl<UserMapper,User>implementsUserService{//无需重写page方法,直接使用父类方法}```**Mapper接口:**```javapublicinterfaceUserMapperextendsBaseMapper<User>{//继承BaseMapper,已经内置了分页相关的方法}```###带条件的分页查询如果需要进行带条件的分页查询,可以使用QueryWrapper来构建查询条件。例如:```java@GetMapping("/pageByCondition")publicR<Page<User>>pageByCondition(@RequestParam(defaultValue="1")intpageNo,@RequestParam(defaultValue="10")intpageSize,@RequestParamStringname){Page<User>page=newPage<>(pageNo,pageSize);QueryWrapper<User>wrapper=newQueryWrapper<>();wrapper.like("name",name);//条件:姓名中包含指定字符串Page<User>userPage=userService.page(page,wrapper);returnR.ok(userPage);}```###说明-`Page<T>`对象不仅包含查询结果的数据列表,还包含分页信息(如当前页、每页大小、总记录数、总页数等)。-MyBatisPlus分页插件会自动将分页查询转换成对应数据库的分页语句(例如MySQL使用LIMIT,Oracle使用ROWNUM等)。-在返回给前端,可以将整个Page对象返回,前端可以获取到分页数据分页信息。###相关问题1.在MyBatisPlus中如何配置多个分页插件?2.如何使用MyBatisPlus实现自定义分页查询(例如多表关联查询分页)?3.如何优化MyBatisPlus分页查询在大数据量下的性能?4.如何在MyBatisPlus中使用XML映射文件进行分页查询?5.如何修改Page对象返回的字段名以满足前端要求?请参考MyBatisPlus官方文档获取更多信息:[MyBatisPlus分页插件](https://baomidou.com/guide/interceptor.html#paginationinnerinterceptor)</think> ### MyBatis Plus 中 `selectPage` 的使用指南 在 MyBatis Plus 中,`selectPage()` 是实现分页查询的核心方法,它直接集成了物理分页功能,避免手动编写 SQL 分页语句[^1]。以下是具体用法和最佳实践: --- #### 1. **基础配置** 首先在配置类中注册分页插件: ```java @Configuration public class MybatisConfig { @Bean public MybatisPlusInterceptor paginationInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } } ``` --- #### 2. **Service 层实现分页查询** 在 Service 接口中定义分页方法: ```java public interface UserService extends IService<User> { Page<User> selectUserPage(Page<User> page, @Param("status") Integer status); } ``` 在 Service 实现类中实现: ```java @Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { @Override public Page<User> selectUserPage(Page<User> page, Integer status) { return baseMapper.selectPage(page, new QueryWrapper<User>().eq("status", status) // 条件构造器 ); } } ``` --- #### 3. **Mapper 层使用** Mapper 接口可直接继承 `BaseMapper`: ```java public interface UserMapper extends BaseMapper<User> { // 无需手动编写分页SQL } ``` --- #### 4. **Controller 层调用** ```java @RestController public class UserController { @Autowired private UserService userService; @GetMapping("/users") public R listUsers( @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "10") int size, @RequestParam(required = false) Integer status) { Page<User> pageParam = new Page<>(page, size); Page<User> result = userService.selectUserPage(pageParam, status); return R.ok().data(result); } } ``` --- #### 5. **返回数据结构示例** ```json { "success": true, "data": { "records": [ // 当前页数据 {"id": 1, "name": "张三", "status": 1}, {"id": 2, "name": "李四", "status": 1} ], "total": 100, // 总记录数 "size": 10, // 每页大小 "current": 1, // 当前页码 "pages": 10 // 总页数 } } ``` --- ### 关键特性说明 1. **自动物理分页** MyBatis Plus 会自动将 `Page` 对象转换为数据库特定的分页语法(如 MySQL 的 `LIMIT`),无需手动拼写 SQL。 2. **条件构造器** 使用 `QueryWrapper` 可灵活添加查询条件: ```java new QueryWrapper<User>() .like("name", "张") .between("create_time", startDate, endDate) ``` 3. **性能优化** - 统计查询优化:默认执行 `SELECT COUNT(1)` 获取总数 - 关闭总数统计:`Page<User> page = new Page<>(page, size, false);` --- ### 最佳实践 1. **DTO 转换** 建议将返回的实体转换为 DTO,避免暴露敏感字段: ```java Page<User> pageData = userService.page(pageParam); Page<UserDTO> dtoPage = pageData.convert(user -> {...}); ``` 2. **复杂查询处理** 多表联查使用自定义 XML/SQL: ```xml <!-- UserMapper.xml --> <select id="selectUserWithDept" resultMap="userDeptMap"> SELECT u.*, d.name dept_name FROM user u LEFT JOIN dept d ON u.dept_id = d.id WHERE ${ew.customSqlSegment} </select> ``` 3. **前端分页参数传递** 推荐统一使用 `page=1&size=10` 格式参数,与 `Page` 对象直接映射[^1]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值