从此
📄文章 #️⃣专题 🌐酷站 👨‍💻技术 📺 📱

🏠 » 📄文章 » 内容

 欢迎来访!

MyBatis 分页 pagehelper-spring-boot-starter 插件集成

🕗2024-08-14👁️1

原理

PageHelper是一个用于MyBatis环境的分页插件,pagehelper-spring-boot-starter是其在Spring Boot框架中的集成组件。下面简要介绍PageHelper的分页原理:

PageHelper的分页原理

  1. 拦截器机制PageHelper通过MyBatis的拦截器机制实现分页功能。它会在SQL执行前拦截并修改SQL语句,添加分页相关的信息。

  2. ThreadLocal存储分页参数:在调用分页查询之前,会将分页参数(如页码、每页数量)存储在当前线程的ThreadLocal中,确保每次查询都能获取到正确的分页信息。

  3. 自动构建分页SQL:根据存储在ThreadLocal中的分页参数,在拦截器中自动构建带有分页逻辑的SQL语句,例如使用LIMITOFFSET来限制返回结果集。

  4. 执行分页查询:当执行带有分页参数的查询时,PageHelper会拦截该查询并根据分页参数重新构建SQL语句,然后执行查询操作。

  5. 封装分页结果:在查询完成后,PageHelper会将查询结果封装成包含分页信息的对象,方便在业务逻辑中使用。

PageHelper-Spring-Boot-Starter的集成原理

  1. 自动配置pagehelper-spring-boot-starter提供了自动配置类,可以根据配置文件中的属性自动配置PageHelper的相关参数,简化了在Spring Boot项目中集成PageHelper的步骤。

  2. 注入拦截器:在自动配置过程中,会向MyBatis的SqlSessionFactory中注入PageInterceptor,这个拦截器负责拦截SQL并处理分页逻辑。

  3. 配置参数:通过在application.propertiesapplication.yml中配置pagehelper相关属性,可以定制化地设置分页参数,如页码参数名、每页数量等。

总的来说,PageHelper通过拦截器机制、ThreadLocal存储分页参数以及自动构建分页SQL来实现对MyBatis的分页支持,而pagehelper-spring-boot-starter则在Spring Boot中简化了PageHelper的集成和配置过程。

实战

下面是一个简单的示例,演示如何在Spring Boot项目中使用pagehelper-spring-boot-starter来实现分页查询:

1. 添加依赖

首先,在pom.xml文件中添加pagehelper-spring-boot-starter的依赖:

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>{version}</version>
</dependency>

2. 配置属性

application.propertiesapplication.yml中配置pagehelper相关属性,例如:

# PageHelper配置
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql

3. 编写Mapper接口和XML文件

编写MyBatis的Mapper接口和对应的XML文件,定义分页查询的方法。

4. 在Service中调用分页查询

在Service类中调用分页查询方法,示例代码如下:

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public PageInfo<User> findUsers(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<User> userList = userMapper.selectUsers();
        return new PageInfo<>(userList);
    }
}

5. Controller层调用Service进行分页查询

在Controller层调用Service中的方法进行分页查询,并返回分页结果给前端。示例代码如下:

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/users")
    public PageInfo<User> getUsers(@RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize) {
        return userService.findUsers(pageNum, pageSize);
    }
}

通过以上步骤,你就可以在Spring Boot项目中使用pagehelper-spring-boot-starter来实现分页查询功能。记得根据具体的业务需求和数据库类型配置相应的pagehelper属性。


在 MyBatis 配置 xml 文件中配置拦截器插件

<!--
    plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下:
    properties?, settings?,
    typeAliases?, typeHandlers?,
    objectFactory?,objectWrapperFactory?,
    plugins?,
    environments?, databaseIdProvider?, mappers?
-->
<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 使用下面的方式配置参数 -->
        <property name="param1" value="value1"/>
    </plugin>
</plugins>

分页插件支持以下几种调用方式:

//第一种,RowBounds方式的调用
List<User> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(0, 10));

//第二种,Mapper接口方式的调用,推荐这种使用方式。
PageHelper.startPage(1, 10);
List<User> list = userMapper.selectIf(1);

//第三种,Mapper接口方式的调用,推荐这种使用方式。
PageHelper.offsetPage(1, 10);
List<User> list = userMapper.selectIf(1);

//第四种,参数方法调用
//存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数
public interface CountryMapper {
    List<User> selectByPageNumSize(
            @Param("user") User user,
            @Param("pageNum") int pageNum,
            @Param("pageSize") int pageSize);
}
//配置supportMethodsArguments=true
//在代码中直接调用:
List<User> list = userMapper.selectByPageNumSize(user, 1, 10);

//第五种,参数对象
//如果 pageNum 和 pageSize 存在于 User 对象中,只要参数有值,也会被分页
//有如下 User 对象
public class User {
    //其他fields
    //下面两个参数名和 params 配置的名字一致
    private Integer pageNum;
    private Integer pageSize;
}
//存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数
public interface CountryMapper {
    List<User> selectByPageNumSize(User user);
}
//当 user 中的 pageNum!= null && pageSize!= null 时,会自动分页
List<User> list = userMapper.selectByPageNumSize(user);

//第六种,ISelect 接口方式
//jdk6,7用法,创建接口
Page<User> page = PageHelper.startPage(1, 10).doSelectPage(new ISelect() {
    @Override
    public void doSelect() {
        userMapper.selectGroupBy();
    }
});
//jdk8 lambda用法
Page<User> page = PageHelper.startPage(1, 10).doSelectPage(()-> userMapper.selectGroupBy());

//也可以直接返回PageInfo,注意doSelectPageInfo方法和doSelectPage
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(new ISelect() {
    @Override
    public void doSelect() {
        userMapper.selectGroupBy();
    }
});
//对应的lambda用法
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(() -> userMapper.selectGroupBy());

//count查询,返回一个查询语句的count数
long total = PageHelper.count(new ISelect() {
    @Override
    public void doSelect() {
        userMapper.selectLike(user);
    }
});
//lambda
        total=PageHelper.count(()->userMapper.selectLike(user));