mybatis-plus paging method

Interceptor (pagination plugin)

One method 1: XxxMapper.selectPage

1 selectPage(page, null)

  1. overview
    1. The (built-in) paging plug-in provided in MyBatisPlus is very simple, and only needs a simple configuration to realize the paging function.
  2. detailed steps:
    1. The first step:: config.MybatisPlusConfig.java: configuration class, configure the plug-in function of mybatisplus.
      package com.guigu.config;
      import com.baomidou.mybatisplus.annotation.DbType;
      import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
      import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
      import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
      import org.mybatis.spring.annotation.MapperScan;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      
      @Configuration
      @MapperScan("com.guigu.mapper") //可以将启动类中的注解移到此处
      public class MybatisPlusConfig {
          /**
           *
           * 1 怎么来配置mybatis-plus中的插件?
           *   这里所需要的类型是MybatisPlusInterceptor,这是mybatis-plus的一个拦截器,用于配置mybatis-plus中的插件。
           * 2 为什么要使用拦截器MybatisPlusInterceptor呢?
           *    这里边的原理和mybatis分页插件的功能是一样的,工作流程如下 :
           *   (1)第一步:执行查询功能。
           *   (2)第二步:拦截器对查询功能进行拦截。
           *   (3)第三步:拦截器对查询功能的基础上做了额外的处理,达到分页的效果(功能)。
           * 3 对比配置mybatis中的插件?
           *   用的也是拦截器的方式。
           *
           * @return MybatisPlusInterceptor
           */
          @Bean
          public MybatisPlusInterceptor mybatisPlusInterceptor() {
              MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
              //添加:分页插件
              //参数:new PaginationInnerInterceptor(DbType.MYSQL),是专门为mysql定制实现的内部的分页插件
              interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
              //添加:乐观锁插件
              interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
              return interceptor;
          }
      }
      
    2. Step 2: Verify (Test):
      package com.guigu;
      import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
      import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
      import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
      import com.guigu.mapper.UserMapper;
      import com.guigu.pojo.User;
      import org.junit.jupiter.api.Test;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.test.context.SpringBootTest;
      import java.util.List;
      import java.util.Map;
      
      @SpringBootTest
      class MybatisplusDemo01ApplicationTests {
          @Autowired
          private UserMapper userMapper;
      
          @Test
          public void testPage(){
              //设置分页参数:页码、显示的条数
              Page<User> page = new Page<>(2, 3);
              //第2个参数是条件构造器,如果设置为null,即查询所有
              //返回值就是一个Page对象,即返回上面所new出来的page对象,所有数据都在其中
              //对应的sql语句:SELECT id,name,age,email FROM user LIMIT ?
              userMapper.selectPage(page, null);
              //获取分页数据
              List<User> list = page.getRecords();
              list.forEach(System.out::println);
              System.out.println("当前页:"+page.getCurrent());
              System.out.println("每页显示的条数:"+page.getSize());
              System.out.println("总记录数:"+page.getTotal());
              System.out.println("总页数:"+page.getPages());
              System.out.println("是否有上一页:"+page.hasPrevious());
              System.out.println("是否有下一页:"+page.hasNext());
          }
      }

2 selectPage(page, lambda query wrapper)

//  这种方式比较简单,可以不用修改Mapper,适合简单的增删改查。
@PostMapping("/queryPage")
public ResponseData<Object> queryPage(@RequestBody QueryPageParam queryPageParam) {
    try {
        int pageIndex = queryPageParam.getPageIndex() == 0 ? 1 : queryPageParam.getPageIndex();
        int pageSize = queryPageParam.getPageSize() == 0 ? 20 : queryPageParam.getPageSize();
        Page<User> page = new Page<>(pageIndex, pageSize);
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class);
        if (CharSequenceUtil.isNotBlank(queryPageParam.getAge())) {
            wrapper.eq(User::getAge, queryPageParam.getAge());
        }
        Page<User> queryPageUser = userMapper.selectPage(page, wrapper);
        return new ResponseData<>(StatusCodeEnum.SUCCESS_CODE.getStatusCode(), queryPageUser.getRecords(),"操作成功");
    } catch (Exception e) {
        log.error("异常信息: " + e.getMessage(), e);
        return new ResponseData<>(StatusCodeEnum.ERROR_CODE.getStatusCode(), "操作失败:" + e.getMessage());
    }
}

Method 2: Service CRUD interface

Official website introduction:

// 无条件分页查询
IPage<T> page(IPage<T> page);
// 条件分页查询
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 无条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page);
// 条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);

IXxxService.java:

package com.example.demo.user.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo.user.entity.User;
 
public interface UserService extends IService<User> {

}

XxxServiceImpl.java:

package com.example.demo.user.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.user.entity.User;
import com.example.demo.user.mapper.UserMapper;
import com.example.demo.user.service.UserService;
import org.springframework.stereotype.Service;
 
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

}

XxxController.java

package com.example.demo.user.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.user.entity.User;
import com.example.demo.user.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
 
@Api(tags = "排序")
@RestController
@RequestMapping("sort")
public class SortController {
 
    @Autowired
    private UserService userService;
 
    @ApiOperation("默认顺序")
    @GetMapping("defaultOrder")
    public IPage<User> defaultOrder(Page<User> page) {
        return userService.page(page);
    }
 
    @ApiOperation("通过orderItems")
    @GetMapping("orderItems")
    public IPage<User> orderItems(Page<User> page) {
        page.addOrder(OrderItem.desc("create_time"));
        // 可以指定多列。比如下边这个:按create_time排序,若create_time相同,则按id排序
        // page.addOrder(OrderItem.desc("create_time"), OrderItem.asc("id"));
        return userService.page(page);
    }
 
    @ApiOperation("通过wrapper")
    @GetMapping("wrapper")
    public IPage<User> wrapper(Page<User> page) {
        LambdaQueryWrapper<User> queryWrapper = Wrappers.<User>lambdaQuery();
        // 按create_time排序,若create_time相同,则按id排序
        queryWrapper.orderByDesc(User::getCreateTime);
        queryWrapper.orderByAsc(User::getId);
        return userService.page(page, queryWrapper);
    }
 
    @ApiOperation("前端指定顺序")
    @GetMapping("byFrontEnd")
    public IPage<User> byFrontEnd(Page<User> page) {
        return userService.page(page);
    }
}

Three ways 3: custom method + paging of custom (dynamic) sql statement

  1. Business (scenario): the query statement is customized
  2. Requirement: How to customize the query statement to cooperate with the paging plug-in to realize the paging function
  3. Case: Query user information based on age, and paging
    1. The first step: UserMapper.java: interface method
      @Repository
      public interface UserMapper extends BaseMapper<User> {
          /**
           * 需求:根据年龄查询用户列表,分页显示
           *
           * 第一步:xml自定义分页,Mapper接口方法
           *       第1步:如果想要mybatis-plus的分布插件来作用于我们自定义的sql语句的话,第一个参数必须得是一个分页对象:@Param("page") Page<User> page。
           * 第二步:因为Mapper接口方法有2个参数的话
           *       方案1:使用mybatis提供的访问方式
           *       方案2:也可以使用@param来设置命名参数,来规定参数的访问规则
           *
           * @param page 必须放在第一位:分页对象,xml中可以从里面进行取值,传递参数 Page 即自动分页
           * @param age 年龄
           * @return Page<User>
           */
          Page<User> selectPageVo(@Param("page") Page<User> page, @Param("age") Integer age);
      }
    2. The second step: UserMapper.xml: custom sql statement
      <?xml version ="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapper
              PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
              "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
      <mapper namespace ="com.guigu.mapper.UserMapper" >
          <sql id="BaseColumns">id,name,age,email</sql>
          <!--IPage<User> selectPageVo(Page<User> page, Integer age);-->
          <!-- 因为现在仍然使用的是mybatis-plus提供的分页插件来实现分页功能,
               所以这里我们只编写查询的sql语句(没有limit),而分页功能的实现还是交给mybatis-plus的分页插件-->
          <!-- resultType="User"中的”User“是类型别名,
               因为之前我们没有设置类型别名”User“(更不是mybatis内置类型别名),
               所以我们要在配置文件application.yml中设置mybatis类型别名”User“,
               之后,我们就可以通过类型别名”User“访问到User.java类型了。-->
          <select id="selectPageVo" resultType="User">
              SELECT <include refid="BaseColumns"></include> FROM user WHERE age > #{age}
          </select>
      </mapper>
    3. Step 3: application.yml: set type alias
      ​
      spring:
        # 配置数据源信息
        datasource:
          dynamic:
            # 设置默认的数据源或者说主数据源,默认值即为master
            primary: master
            # 严格匹配数据源,默认false.true未匹配到指定数据源时抛异常,false未匹配到指定数据源时使用默认数据源
            strict: false
            datasource:
                master:
                  url: jdbc:mysql://localhost:3306/fLearn?characterEncoding=utf-8&useSSL=false
                  driver-class-name: com.mysql.cj.jdbc.Driver
                  username: root
                  password: MySQL#567890
                #从数据源
                slave_1:
                  url: jdbc:mysql://localhost:3306/fLearn2?characterEncoding=utf-8&useSSL=false
                  driver-class-name: com.mysql.cj.jdbc.Driver
                  username: root
                  password: MySQL#567890
      mybatis-plus:
        configuration:
          log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
        #配置mybatis类型别名所对应的包
        #此配置后,默认把类名当做此类型的别名,且不区分大小写(resultType="User"和resultType="user"都是指向User.java类型)
        type-aliases-package: com.guigu.pojo
        # 配置扫描通用枚举所在的包
        type-enums-package: com.guigu.enums
      
      ​
    4. Step 4: XmlPage.java: Test

      package com.guigu;
      import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
      import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
      import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
      import com.guigu.mapper.UserMapper;
      import com.guigu.pojo.User;
      import org.junit.jupiter.api.Test;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.test.context.SpringBootTest;
      import java.util.List;
      import java.util.Map;
      
      @SpringBootTest
      class xmlPage {
          @Autowired
          private UserMapper userMapper;
          @Test
          public void testSelectPageVo(){
              //设置分页参数
              Page<User> page = new Page<>(1, 5);
              userMapper.selectPageVo(page, 20);
              //获取分页数据
              List<User> list = page.getRecords();
              list.forEach(System.out::println);
              System.out.println("当前页:"+page.getCurrent());
              System.out.println("每页显示的条数:"+page.getSize());
              System.out.println("总记录数:"+page.getTotal());
              System.out.println("总页数:"+page.getPages());
              System.out.println("是否有上一页:"+page.hasPrevious());
              System.out.println("是否有下一页:"+page.hasNext());
          }
      }

Four ways 4: PageHelper plug-in pagination query

  1. The first step: pom.xml: dependency
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>1.4.5</version>
            </dependency>
    
  2. Step 2: XxxServiceImpl.java: Implementation of the Service CRUD interface

        @Override
        public PageInfo<SchoolStudent> getPageStudentFour(Integer current, Integer size) {
            //获取第1页,10条内容,默认查询总数count
            PageHelper.startPage(current, size);
            List<SchoolStudent> list = this.list();
            //用PageInfo对结果进行包装
            PageInfo page = new PageInfo(list);
            return page;
        }
    
  3. Step Three: Test

    1. This is the query statement printed by the console. Everyone found that the last LIMIT function is missing. Normally, it is not written in mybatis-plus, but it is added by pagehelper. I suddenly felt that as a junior programmer, I still have a lot to learn.

    2. PageHelper.startPage(pageNum, pageSize) The two values ​​set in this place, pagehelper will help you add them when you execute the query statement, that is, the two parameters of LIMIT, the first parameter is the starting subscript of LIMIT, pagehelper will automatically calculate it for you based on pageNum and pageSize; the second parameter is the data volume of LIMIT, which is pageSize. And I found that pagehelper will execute the query statement you wrote twice. The first pass will perform count(0) to find out the total number of entries, and the second pass will use the parameters you set to help you query pageSize pieces of data.

    3. My previous idea of ​​sorting the tree first and then paginating it will not work when using pagehelper, because it will affect the automatic paging of pagehelper. Therefore, I concluded that other sorting operations cannot be performed on the queried data when performing pagehelper paging (it is possible to write order by in the query statement). This may be the limitation of pagehelper, but I believe there should be a solution. I'll share it when I find it.

five references

(1)sgg - yangbochao -mybatisplus  

(2) Mybatis-plus paging query three methods_mybatisplus paging query - pageHelps

(3) Two ways of Mybatis-plus paging - selectPage(page, lambda query wrapper) 

(4) The implementation of sorting when MyBatisPlus paging - XxxService.page() method 

Guess you like

Origin blog.csdn.net/aiwokache/article/details/129176894
Recommended