mybatis分页插件

Mybatis插件用于语句执行过程中进行拦截,通过自定义处理程序来拦截和修改SQL语句、映射语句的结果等。 MyBatis的插件机制包括以下三个组件:

  1. Interceptor(拦截器):定义一个拦截方法Intercept,该方法在执行SQL语句、执行查询、查询结果的映射时会被调用。
  2. Invocation(调用):实际上是对被拦截的方法的封装,封装了 Object target、Method method 和 Object\[\] args 这三个字段。
  3. InterceptorChain(拦截器链):对所有的拦截器进行管理,包括将所有的 interceptor 链接成一条链,并在执行 SQL 语句时按顺序调用。

正常写sql语句,不用添加limit,不要使用;结尾。 使用PageHelp插件,只需要page, pageSize。 SQL -> PageHelper插件 -> SQL + limit x(偏移量, (page-1)*pageSize), y(查询数量,pageSize);

MyBatis PageHelper 分页插件使用指南

1. 添加依赖

pom.xml 中添加 PageHelper 依赖:

xml 复制代码
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.3.3</version>
</dependency>

2. 配置 PageHelper

在 MyBatis 配置文件 mybatis-config.xml 中添加插件配置:

xml 复制代码
<configuration>
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <property name="helperDialect" value="mysql"/>
            <!-- 分页合理化 -->
            <property name="reasonable" value="true"/>
            <!-- 支持通过 Mapper 接口参数来传递分页参数 -->
            <property name="supportMethodsArguments" value="true"/>
            <property name="params" value="count=countSql"/>
        </plugin>
    </plugins>
</configuration>

如果使用 Java 配置方式,可以这样配置:

java 复制代码
@Configuration
public class MybatisConfig {
    @Bean
    public PageInterceptor pageInterceptor() {
        PageInterceptor pageInterceptor = new PageInterceptor();
        Properties properties = new Properties();
        properties.setProperty("helperDialect", "mysql");
        properties.setProperty("reasonable", "true");
        properties.setProperty("supportMethodsArguments", "true");
        properties.setProperty("params", "count=countSql");
        pageInterceptor.setProperties(properties);
        return pageInterceptor;
    }
}

## 3. 使用示例

### 3.1 基本使用方法
```java
// 在查询之前调用 PageHelper.startPage
PageHelper.startPage(pageNum, pageSize);
List<User> users = userMapper.selectAll();

// 获取分页信息
PageInfo<User> pageInfo = new PageInfo<>(users);

3.2 Service 层示例

java 复制代码
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    
    public PageInfo<User> getUserList(int pageNum, int pageSize) {
        // 设置分页
        PageHelper.startPage(pageNum, pageSize);
        // 查询数据
        List<User> users = userMapper.selectAll();
        // 返回分页信息
        return new PageInfo<>(users);
    }
}

3.3 Controller 层示例

java 复制代码
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;
    
    @GetMapping("/list")
    public PageInfo<User> getUserList(
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize) {
        return userService.getUserList(pageNum, pageSize);
    }
}

3.4 Mapper 接口示例

java 复制代码
@Mapper
public interface UserMapper {
    // 不需要在 SQL 中写分页语句
    List<User> selectAll();
}

3.5 XML 映射文件示例

xml 复制代码
<select id="selectAll" resultType="com.example.entity.User">
    SELECT * FROM user
    <!-- 不需要写 LIMIT 语句,PageHelper 会自动添加 -->
</select>

4. PageInfo 对象包含的分页信息

  • pageNum:当前页码
  • pageSize:每页数量
  • size:当前页的数量
  • total:总记录数
  • pages:总页数
  • list:查询结果
  • prePage:前一页
  • nextPage:下一页
  • isFirstPage:是否为第一页
  • isLastPage:是否为最后一页
  • hasPreviousPage:是否有前一页
  • hasNextPage:是否有下一页
  • navigatePages:导航页码数
  • navigatePageNums:所有导航页号

5. 高级用法

5.1 带条件的分页查询

java 复制代码
// Service层
public PageInfo<User> searchUsers(String keyword, int pageNum, int pageSize) {
    PageHelper.startPage(pageNum, pageSize);
    List<User> users = userMapper.searchByKeyword(keyword);
    return new PageInfo<>(users);
}

// Mapper接口
List<User> searchByKeyword(@Param("keyword") String keyword);

// XML映射
<select id="searchByKeyword" resultType="User">
    SELECT * FROM user 
    WHERE username LIKE CONCAT('%', #{keyword}, '%')
</select>

5.2 排序查询

java 复制代码
// 按年龄降序
PageHelper.startPage(pageNum, pageSize, "age desc");
List<User> users = userMapper.selectAll();

// 多字段排序
PageHelper.startPage(pageNum, pageSize, "age desc, create_time asc");

5.3 不要分页的情况

java 复制代码
// 使用 PageHelper.clearPage() 清除分页内容
PageHelper.clearPage();
List<User> allUsers = userMapper.selectAll();

6. 注意事项

  1. 线程安全:PageHelper 使用 ThreadLocal 保证线程安全,但要注意在线程池环境下需要清理。

  2. 分页参数合理化

yaml 复制代码
pagehelper:
  reasonable: true  # 当页数小于1时自动查询第一页,大于最后一页时查询最后一页
  1. 性能考虑
  • 避免使用太大的页码数
  • 合理设置每页数量
  • 对于大数据量建议使用物理分页
  1. Count 查询优化
yaml 复制代码
pagehelper:
  page-size-zero: true  # 当 pageSize=0 时查询所有结果

7. 常见问题解决

  1. 分页失效问题
  • 确保 PageHelper.startPage() 紧跟着执行查询语句
  • 不要在 PageHelper.startPage() 后进行多次查询
  1. Count 查询优化
java 复制代码
// 设置不进行 count 查询
PageHelper.startPage(pageNum, pageSize, false);
  1. 排序问题
java 复制代码
// 使用 PageHelper 的排序功能
String orderBy = "create_time desc";
PageHelper.startPage(pageNum, pageSize).setOrderBy(orderBy);
相关推荐
考虑考虑10 小时前
Mybatis实现批量插入
java·后端·mybatis
敲个大西瓜14 天前
mybatis拦截器插件实现数据库字段加解密
mybatis
武子康14 天前
Java-28 深入浅出 Spring 实现简易Ioc-04 在上节的业务下手动实现AOP
java·后端·mybatis
一条泥憨鱼14 天前
苍穹外卖【day6|微信登录与商品浏览功能】
后端·mybatis·苍穹外卖
vx-Biye_Design14 天前
springboot安阳地区研学旅游服务小程序-计算机毕业设计源码12785
java·vue.js·windows·spring boot·tomcat·maven·mybatis
摇滚侠14 天前
MyBatis+Spring+SpringMVC SSM 整合 179-185
java·spring·mybatis
摇滚侠14 天前
MyBatis+Spring+SpringMVC SSM ContextLoaderListener 177-178
java·spring·mybatis
Spring小子15 天前
【Spring Boot + Vue + DeepSeek】从零打造一个AI驱动的智能健康分析系统
java·spring boot·mybatis
武子康15 天前
Java-27 深入浅出 Spring - 实现简易Ioc-03 在上节的业务下手动实现IoC 从 XML 配置到 BeanFactory 反射注入
java·后端·mybatis