title: 使用分页插件的后悔药(二) tags:
- PageHelper
- Mybatis 通用 Mapper
- orderByOnly
- 分页
- mybatis categories: mybatis date: 2018-01-03 16:46:13
背景
我们使用了pageHelper之后大部分的需求可以满足了 部分场景下不需要使用count等语句来做分页,只需要做sql查询
上一篇我们对于分页插件的问题进行了一些描述以及解决1
问题
小伙伴在使用了一段时间之后提出了新的需求。现在使用了分页插件之后已经不写orderby语句了
但是在某些场景下现在不需要使用分页 但是仍然需要使用orderby
我们在使用分页插件的后悔药中 提到使用enableCount的参数来解决
但是这样分页插件的逻辑将不会执行了 也就不会执行orderby
有没有办法也使用到orderby呢???
解决
抛出一个问题 当然是要解决的 我们来看一下具体执行分页的逻辑是啥
@Override
public boolean skip(MappedStatement ms, Object parameterObject, RowBounds rowBounds) {
Page page = sqlUtil.getPage(parameterObject, rowBounds);
if (page == null) {
return true;
}
return (page.getPageSizeZero() != null && page.getPageSizeZero()) && page.getPageSize() == 0;
}
复制代码
上篇已经分析过可以设置pageSize 那我们需要分页插件的逻辑只是不希望执行count有没有办法呢?
@Override
public boolean beforeCount(MappedStatement ms, Object parameterObject, RowBounds rowBounds) {
Page page = SqlUtil.getLocalPage();
return !page.isOrderByOnly() && page.isCount();
}
复制代码
很明显还有一个参数名为orderByOnly
顾名思义应该是制作排序【那自然不需要count了】
我们再看一下在做查询的时候是否也不会吧页数设置进去
@Override
public String getPageSql(MappedStatement ms, BoundSql boundSql, Object parameterObject, RowBounds rowBounds, CacheKey pageKey) {
String sql = boundSql.getSql();
Page page = SqlUtil.getLocalPage();
//支持 order by
String orderBy = page.getOrderBy();
if (StringUtil.isNotEmpty(orderBy)) {
pageKey.update(orderBy);
sql = OrderByParser.converToOrderBySql(sql, orderBy);
}
if (page.isOrderByOnly()) {
return sql;
}
return getPageSql(sql, page, rowBounds, pageKey);
}
复制代码
很明显当isOrderByOnly设置时此时分页也不会执行。
因此我们改造SoInterceptor如下
@Intercepts(@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}))
public class SoInterceptor implements Interceptor {
private static final Joiner SORT_JOINER = Joiner.on(Constants.COMMA);
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object paramter = invocation.getArgs()[1];
if (paramter instanceof So) {
So so = (So) paramter;
Page<Object> page = PageHelper.startPage(so.getCurrentPage(), so.getPageSize(), so.isEnableCount());
page.setOrderByOnly(so.isOrderByOnly());
if (so.getSorts() != null && !so.getSorts().isEmpty()) {
page.setOrderBy(SORT_JOINER.join(so.getSorts()));
}
try {
return invocation.proceed();
} finally {
PageHelper.clearPage();
}
}
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
if (target instanceof Executor) {
return Plugin.wrap(target, this);
} else {
return target;
}
}
@Override
public void setProperties(Properties properties) {
// Do nothing
}
}
复制代码
这样就可以既不分页也带排序了【条件带上orderByOnly=true】