pagehelper庫(https://github.com/pagehelper/Mybatis-PageHelper)是java后端開發領域比較常用的分頁插件庫,能夠很好的實現分頁需求。這次記錄一下他的另外一個功能,就是在分頁的同時傳入自定義的排序條件,比如會遇到如下需求,分頁查詢某些表格數據后,再對某個字段進行升序或降序排序。
設置排序的源碼如下(PageMethod):
/** * 開始分頁 * * @param pageNum 頁碼 * @param pageSize 每頁顯示數量 * @param orderBy 排序 */ public static <E> Page<E> startPage(int pageNum, int pageSize, String orderBy) { Page<E> page = startPage(pageNum, pageSize); page.setOrderBy(orderBy); return page; }
此處傳入的orderBy字符串需形如(假如按照id排序):"id asc"或"id desc"。
解析排序,組裝sql的源碼如下(PageInterceptor):
@Override public Object intercept(Invocation invocation) throws Throwable { try { Object[] args = invocation.getArgs(); MappedStatement ms = (MappedStatement) args[0]; ......//調用方言獲取分頁 sql String pageSql = dialect.getPageSql(ms, boundSql, parameter, rowBounds, pageKey); ...... } }
AbstractHelperDialect:
@Override public String getPageSql(MappedStatement ms, BoundSql boundSql, Object parameterObject, RowBounds rowBounds, CacheKey pageKey) { String sql = boundSql.getSql(); Page page = 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, pageKey); }
OrderByParser:
/** * convert to order by sql * * @param sql * @param orderBy * @return */ public static String converToOrderBySql(String sql, String orderBy) { //解析SQL Statement stmt = null; try { stmt = CCJSqlParserUtil.parse(sql); Select select = (Select) stmt; SelectBody selectBody = select.getSelectBody(); //處理body-去最外層order by List<OrderByElement> orderByElements = extraOrderBy(selectBody); String defaultOrderBy = PlainSelect.orderByToString(orderByElements); if (defaultOrderBy.indexOf('?') != -1) { throw new RuntimeException("原SQL[" + sql + "]中的order by包含參數,因此不能使用OrderBy插件進行修改!"); } //新的sql sql = select.toString(); } catch (Throwable e) { e.printStackTrace(); } return sql + " order by " + orderBy; }
實際上最后的實現思路還是拼接sql,將order by的條件拼接到sql語句中。