MyBatis-plus 分页查询

一、分页查询常用方式

  1. MyBatis-Plus中最常用的分页查询的方法是结合 IPage 接口和 Page 类来实现,也是 MyBatis-Plus 官方推荐的方式。
  2. 同时还支持使用 PageHelper 插件进行分页查询,但这通常用于 MyBatis 原生集成,而不是 MyBatis-Plus

二、使用 IPage 进行分页查询

2.1 IPage 分页查询原理

MyBatis-Plus的 IPage 分页插件主要是通过AOP(面向切面编程)技术来实现的,它可以在运行时动态地拦截方法调用,并在方法执行前后添加额外的行为。这种方式使得分页功能可以很容易地集成到现有的代码中,而不需要对现有查询逻辑做出大的改动。其工作原理如下:

  1. IPage接口: IPage接口定义了分页相关的方法,包括设置当前页码、每页条数、总条数、是否计数等属性和方法。Page类实现了IPage接口,是一个具体的分页对象。
  2. 分页插件: MyBatis-Plus提供了分页插件,该插件在MyBatis执行查询之前介入,根据传入的IPage对象构造出对应的分页SQL语句。
  3. 查询方法: 在MyBatis-Plus中,查询方法通常接受IPage对象作为参数之一。当调用这些查询方法时,分页插件会截取方法参数,并结合IPage对象中的分页参数生成带有分页逻辑的SQL语句。
  4. 执行查询: 分页插件生成的SQL语句被传递给MyBatis执行,MyBatis执行查询并获取结果集。
  5. 封装结果: 查询结果被MyBatis-Plus封装成IPage对象,其中包含了总条数、当前页数据列表、总页数等信息。
  6. 返回结果: 最终,调用者获取到的是封装了分页信息的IPage对象,而不是直接的数据结果集。
2.2 IPage 在Spring Boot项目使用实例

在Spring Boot项目中使用MyBatis-plus进行分页查询通常遵循以下步骤:

  1. 在pom.xml文件中添加依赖:
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>版本号</version>
</dependency>
  1. 在application.properties或application.yml文件中配置数据库连接信息以及开启MyBatis-plus自动映射功能:
## mysql数据库
spring:
  datasource:
    dynamic:
      datasource:
        master:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&useInformationSchema=true
          username: root
          password: root

## mybatis-plus配置信息
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    banner: false
    enable-sql-runner: true
    db-config:
      id-type: ASSIGN_ID
      logic-delete-field: DELETE_FLAG
      logic-delete-value: DELETED
      logic-not-delete-value: NOT_DELETE
  mapper-locations: classpath*:com/test/**/mapping/*.xml,com/bstek/**/mapping/*.xml
  type-handlers-package: com.test.common.handler
  pagination:
    type: OFFSET
  1. 新建一个Mybatis-Plus的插件配置类,在里面添加分页拦截器,如果不添加分页拦截器,使用IPage进行分页查询的结果中的records任然会是全部的数据。
@Configuration
public class MybatisPlusConfig {

    /**
     * IPage的分页使用的是拦截器,属于物理分页,好处就是处理大量数据时,查询速度快。
     *
     * @return MybatisPlus拦截器
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 向MybatisPlus拦截器链中添加分页拦截器
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }
}
  1. 接下来就是接口调用过程,首先创建个接口来获取分页数据。
@GetMapping("/sys/page")
public IPage<SysDTO> page(SysPageParam sysPageParam) {
    return sysService.page(sysPageParam);
}
  1. 定义service接口并继承IService接口
public interface SysService extends IService<SysEntity> {

    /**
     * 获取最近使用分页
     */
    IPage<SysRecentlyUsedDTO> page(SysRecentlyUsedPageParam sysRecentlyUsedPageParam);
}
  1. 定义service实现类并继承ServiceImpl类
/**
 * 如果是单表操作,直接通过IService接口中提供的page方法进行分页查询
 * 就不需要编写Mapper.xml
 **/
@Service
public class SysServiceImpl extends ServiceImpl<SysMapper, SysEntity> implements SysService {
	
	@Override
    public IPage<SysDTO> page(SysPageParam sysPageParam) {
        Page<SysDTO> page = new Page<>(sysPageParam.getCurrent(), sysPageParam.getSize());
        QueryWrapper<SysOrg> queryWrapper = new QueryWrapper<>();
        return this.page(page, queryWrapper);
    }
}
/**
 * 如果是复杂的查询,就需要通过xml中的自定义sql查询分页
 *
 **/
@Service
public class SysServiceImpl extends ServiceImpl<SysMapper, SysEntity> implements SysService {
	
	@Resource
    private SysMapper sysMapper;
	
	@Override
    public IPage<SysDTO> page(SysPageParam sysPageParam) {
        Page<SysDTO> page = new Page<>(sysPageParam.getCurrent(), sysPageParam.getSize());
        QueryWrapper<SysDTO> queryWrapper = new QueryWrapper<>();
        return sysMapper.selectSysDto(page, queryWrapper);
    }
}
  1. 定义Mapper接口并继承BaseMapper
public interface SysMapper extends BaseMapper<SysEntity> {

    IPage<SysDTO> selectSysDto(Page<SysDTO> page, @Param("queryParam") QueryWrapper<SysDTO> queryWrapper);
}
  1. 编写Mapper.xml
<?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.test.web.sys.org.mapper.SysMapper">

    <select id="selectSysDto" resultType="com.test.web.sys.org.dto.SysDTO">
        SELECT
            si.ORG_ID,
            si.USER_ID,
            o.NAME AS orgName,
            u.NAME AS userName
        FROM
            SYS_INFO si
                LEFT JOIN SYS_ORG o ON si.ORG_ID = o.ID
                LEFT JOIN SYS_USER u ON si.USER_ID = u.ID
        WHERE si.DELETE_FLAG = 'NOT_DELETE'
        ORDER BY si.USED_TIME DESC
    </select>

</mapper>

三、使用 PageHelper 进行分页查询

3.1 PageHelper分页插件的工作原理

PageHelper分页插件的工作原理基于MyBatis的拦截器模式,通过拦截MyBatis的执行过程,动态地在查询语句前添加分页逻辑。具体步骤如下:

  1. 拦截器: PageHelper利用MyBatis的拦截器机制,在MyBatis执行查询操作之前拦截调用。拦截器会分析传入的分页参数,并根据这些参数构建分页SQL。
  2. 动态SQL: 根据传入的pageNum(当前页码)和pageSize(每页数量)参数,PageHelper在查询语句的前面动态地添加对应数据库的分页语法。例如,在MySQL中添加LIMIT子句,在Oracle中添加ROWNUM条件。
  3. 执行查询: PageHelper将修改后的分页查询语句交给MyBatis执行,MyBatis执行原始的查询逻辑,但由于已经加入了分页语法,所以实际只会返回分页后的数据集。
  4. 获取分页结果: MyBatis执行查询后,PageHelper会从结果集中提取必要的分页信息(如总记录数、当前页数据等),并将这些信息封装成PageInfo对象返回。
  5. 参数处理: PageHelper支持多种方式来识别分页参数,可以通过方法参数、URL参数等多种方式传递分页信息,并且支持自定义参数名。
  6. 性能优化: PageHelper考虑到性能问题,会尽量避免全表扫描,并且在一些情况下会使用游标而非立即执行查询,以减少内存消耗。
  7. 数据库兼容性: PageHelper支持多种数据库,并且针对不同数据库的分页语法做了适配,这样开发者就不需要为不同数据库编写不同的分页逻辑。
  8. 配置灵活性: PageHelper提供了丰富的配置选项,允许开发者根据自己的需求调整分页行为,比如是否开启合理模式、是否支持方法参数分页等。
3.2 PageHelper在Spring Boot项目使用实例

在Spring Boot项目中集成并使用PageHelper分页插件进行查询,通常需要以下步骤:

  1. 在项目的pom.xml文件中添加PageHelper的Maven依赖。
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>版本号</version>
</dependency>
  1. 在application.yml或者application.properties文件中配置PageHelper的相关属性。
pagehelper:
  reasonable: true  # 是否进行分页合理化
  supportMethodsArguments: true  # 是否支持通过Mapper接口参数来传递分页参数
  1. 编写Mapper接口,在Mapper接口中定义分页查询的方法,不需要添加任何分页的注解或逻辑。
public interface UserMapper {
    List<User> selectUsers();
}
  1. 使用分页查询,在服务层或控制器层,使用PageHelper的静态方法startPage来启用分页功能,然后执行查询操作。
@RestController
public class UserController {

    @Autowired
    private UserMapper userMapper;

    @GetMapping("/users")
    public PageInfo<User> listUsers(@RequestParam(defaultValue = "1") int pageNum,
                                     @RequestParam(defaultValue = "10") int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<User> users = userMapper.selectUsers();
        return new PageInfo<>(users);
    }
}
在上面的代码中,listUsers方法通过调用PageHelper.startPage方法来开启分页,并传入当前页码pageNum和每页大小pageSize。
随后执行userMapper.selectUsers()方法来查询数据。查询结果会自动包含分页信息。
  • 28
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值