Mybatis插件用于语句执行过程中进行拦截,通过自定义处理程序来拦截和修改SQL语句、映射语句的结果等。 MyBatis的插件机制包括以下三个组件:
- Interceptor(拦截器):定义一个拦截方法Intercept,该方法在执行SQL语句、执行查询、查询结果的映射时会被调用。
- Invocation(调用):实际上是对被拦截的方法的封装,封装了 Object target、Method method 和 Object[] args 这三个字段。
- 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. 注意事项
-
线程安全:PageHelper 使用 ThreadLocal 保证线程安全,但要注意在线程池环境下需要清理。
-
分页参数合理化:
yaml
pagehelper:
reasonable: true # 当页数小于1时自动查询第一页,大于最后一页时查询最后一页
- 性能考虑:
- 避免使用太大的页码数
- 合理设置每页数量
- 对于大数据量建议使用物理分页
- Count 查询优化:
yaml
pagehelper:
page-size-zero: true # 当 pageSize=0 时查询所有结果
7. 常见问题解决
- 分页失效问题:
- 确保 PageHelper.startPage() 紧跟着执行查询语句
- 不要在 PageHelper.startPage() 后进行多次查询
- Count 查询优化:
java
// 设置不进行 count 查询
PageHelper.startPage(pageNum, pageSize, false);
- 排序问题:
java
// 使用 PageHelper 的排序功能
String orderBy = "create_time desc";
PageHelper.startPage(pageNum, pageSize).setOrderBy(orderBy);