Mybatis如何实现分页
关键字limit实现分页
Interceptor Plugin实现分页
首先定一个拦截器,拦截器会拦截所有以ByPage结尾的方法,然后拼接sql 语句的limit关键字实现分页
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class MyPageInterceptor implements Interceptor {
private int page;
private int size;
@SuppressWarnings("unused")
private String dbType;
@SuppressWarnings("unchecked")
@Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
while (metaObject.hasGetter("h")) {
Object object = metaObject.getValue("h");
metaObject = SystemMetaObject.forObject(object);
}
while (metaObject.hasGetter("target")) {
Object object = metaObject.getValue("target");
metaObject = SystemMetaObject.forObject(object);
}
MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
String mapId = mappedStatement.getId();
if (mapId.matches(".+ByPage$")) {
ParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("delegate.parameterHandler");
Map<String, Object> params = (Map<String, Object>) parameterHandler.getParameterObject();
page = (int) params.get("page");
size = (int) params.get("size");
String sql = (String) metaObject.getValue("delegate.boundSql.sql");
sql += " limit " + (page - 1) * size + "," + size;
metaObject.setValue("delegate.boundSql.sql", sql);
}
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
String limit = properties.getProperty("limit", "10");
this.page = Integer.parseInt(limit);
this.dbType = properties.getProperty("dbType", "mysql");
}
}
修改controller的findByUserPager方法,拦截器已经自动帮我们算好了page和size的值
public Pager<User> findByUserPager(int page, int size){
Map<String, Object> params = new HashMap<String, Object>();
params.put("page", page);
params.put("size", size);
List<User> list = userMapper.findUserByPage(params);
Pager<User> pager = new Pager<User>();
pager.setData(list);
pager.setTotal(userMapper.findUserCount());
return pager;
}
PageHelper实现分页
//第二种,Mapper接口方式的调用,推荐这种使用方式。
PageHelper.startPage(1, 10);
// Page<User> page = PageHelper.startPage(1, 10);
List<User> list = userMapper.selectIf(1);
//第三种,Mapper接口方式的调用,推荐这种使用方式。
PageHelper.offsetPage(1, 10);
List<User> list = userMapper.selectIf(1);
在你需要进行分页的 MyBatis 查询方法前调用 PageHelper.startPage 静态方法即可,紧跟在这个方法后的第一个MyBatis 查询方法会被进行分页。
分页原理:PageHelper.startPage会拦截下一个sql,也就是userMapper.selectIf(1)的SQL。并且根据当前数据库的语法,把这个SQL改造成一个高性能的分页SQL,同时还会查询该表的总行数,具体可以看SQL日志。
PageHelper.startPage和userMapper.selectIf(1)最好紧跟在一起,中间不要有别的逻辑,否则可能出BUG。
Page<User> page:相当于一个list集合,selectIf(1)方法查询完成后,会给page对象的相关参数赋值。
public PageInfo<User> testPage(User user, Pageable pageable) {
int page = pageable.getPageNum();
int size = pageable.getPageSize();
//项目里自定义的pojo类
User tempuser = new User();
tempuser.setName(user.getName());
//重点就是这句
PageHelper.startPage(page, size);
//这里调用的是mybatis的mapper
List<Userl> tempusers = UserDao.selectByPage(tempuser);
//用PageInfo包装了一下(官方推荐)
return new PageInfo<>(tempusers);
}
本文介绍了Mybatis实现分页的三种方式:通过关键字limit、Interceptor Plugin拦截器以及PageHelper辅助类。Interceptor Plugin通过拦截特定方法并拼接SQL的limit实现分页,而PageHelper则更简单,只需在查询前调用startPage方法,它会自动转换SQL并获取总行数,提供高性能的分页功能。
429

被折叠的 条评论
为什么被折叠?



