zoukankan      html  css  js  c++  java
  • pagehelper对于排序的支持

    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语句中。

  • 相关阅读:
    Windows向虚拟机Linux传输文件方法
    Postgresql ERROR: permission denied for relation app_info
    Spring Boot: Cannot determine embedded database driver class for database type NONE
    零宽度正预测先行断言是什么呢,看msdn上的官方解释定义
    php 的curl 模拟登陆
    使用ProxychainsMac下安装及配置
    利用onekeyup即可实现验证码的点击刷新功能
    程序中使用gc_enable() 和 gc_disable()开启和关闭
    通过ReflectionMethod,我们可以得到Person类的某个方法的信息
    order by id asc得出的排序是什么原理
  • 原文地址:https://www.cnblogs.com/silenceshining/p/14757626.html
Copyright © 2011-2022 走看看