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);
相关推荐
BillKu2 小时前
Java + Spring Boot + Mybatis 插入数据后,获取自增 id 的方法
java·tomcat·mybatis
烙印6015 小时前
MyBatis原理剖析(二)
java·数据库·mybatis
李少兄1 天前
解决MyBatis参数绑定中参数名不一致导致的错误问题
mybatis
异常君1 天前
MyBatis 中 SqlSessionFactory 和 SqlSession 的线程安全性深度分析
java·面试·mybatis
bing_1582 天前
跨多个微服务使用 Redis 共享数据时,如何管理数据一致性?
redis·微服务·mybatis
云之兕2 天前
MyBatis 的动态 SQL
数据库·sql·mybatis
loser.loser2 天前
QQ邮箱发送验证码(Springboot)
java·spring boot·mybatis
毅航2 天前
Trae复刻Mybatis之旅(一):创建SqlSession会话,构建代理
后端·mybatis·trae
潮流coder2 天前
mybatis的if判断==‘1‘不生效,改成‘1‘.toString()才生效的原因
java·tomcat·mybatis