2种奇葩的分页

/**
 * 基类:数据层
 * 
 * @author SilverSpray
 *
 * @param <M>
 */
@SuppressWarnings({ "serial", "unchecked" })
public abstract class BaseModel<M extends BaseModel<M>> extends Model<M> {

    /**
     * 奇葩分页之 刷到指定主键值所在页
     * 
     * @param pageNumber
     * @param pageSize
     * @param sqlPara
     * @param pks
     * @return
     */
    public Page<M> paginateByPk(int pageNumber, int pageSize, SqlPara sqlPara, Object... pks) {
        Long pageNumberPk = getPageNumberByPk(pageSize, sqlPara, pks);
        if (pageNumberPk != null) {
            pageNumber = pageNumberPk.intValue();
        }
        return paginate(pageNumber, pageSize, sqlPara);
    }

    /**
     * 普通分页加了料,使其支持了什么奇怪的..
     * 
     * @param sqlPara
     * @param pager
     * @return
     */
    public Page<M> paginate(SqlPara sqlPara, PagerVo pager) {
        if (pager != null && pager.hasPageSelId()) {
            return paginateByPk(pager.getPageNumber(), pager.getPageSize(), sqlPara, pager.getPageSelId());
        }
        return paginate(pager.getPageNumber(), pager.getPageSize(), sqlPara);
    }

    /**
     * 奇葩分页之 从指定主键值后开始刷新
     * 
     * @param sqlPara
     * @param pager
     * @return
     */
    public List<M> list(SqlPara sqlPara, IncrVo pager) {
        if (!pager.hasPageFromId()) {
            return this.paginate(1, pager.getPageSizeFirst(), sqlPara).getList();
        }
        Long order = getQueryResultOrderByPk(sqlPara, pager.getPageFromId());
        SqlPara listSqlPara = new SqlPara();
        listSqlPara.setSql(forQueryResultFromOrder(this._getTable(), sqlPara.getSql()));
        for (Object para : sqlPara.getPara()) {
            listSqlPara.addPara(para);
        }
        listSqlPara.addPara(order);
        return this.paginate(1, pager.getPageSize(), listSqlPara).getList();
    }

    /**
     * 获取指定主键的数据在查询结果中的顺序号
     * 
     * @param sqlPara
     * @param pks
     * @return
     */
    protected Long getQueryResultOrderByPk(SqlPara sqlPara, Object... pks) {
        SqlPara orderSqlPara = new SqlPara();
        orderSqlPara.setSql(forQueryResultOrder(this._getTable(), sqlPara.getSql()));
        for (Object para : sqlPara.getPara()) {
            orderSqlPara.addPara(para);
        }
        for (Object pk : pks) {
            orderSqlPara.addPara(pk);
        }
        Long orderNumber = Db.queryLong(orderSqlPara.getSql(), orderSqlPara.getPara());
        return orderNumber;
    }

    /**
     * 获取指定主键的数据所在页数
     * 
     * @param pageSize
     * @param sqlPara
     * @param pks
     * @return
     */
    protected Long getPageNumberByPk(int pageSize, SqlPara sqlPara, Object... pks) {
        Long orderNumber = getQueryResultOrderByPk(sqlPara, pks);
        if (orderNumber == null || orderNumber < 1L) {
            return null;
        }
        return (long) Math.ceil((double) orderNumber / (double) pageSize);
    }

    /**
     * sql拼接之 从指定顺序号之后查询
     * 
     * @param table
     * @param querySql
     * @return
     */
    protected String forQueryResultFromOrder(Table table, String querySql) {
        StringBuilder sql = new StringBuilder("select _tmp2.* from ");
        sql.append("(");
        sql.append("select ").append("_tmp1.* ").append(",ROW_NUMBER () OVER () AS _od from");
        sql.append("(").append(querySql).append(") _tmp1 ");
        sql.append(") _tmp2 ");
        sql.append("where _od > ? ");
        return sql.toString();
    }

    /**
     * sql拼接之 指定主键数据的顺序号
     * 
     * @param table
     * @param querySql
     * @return
     */
    protected String forQueryResultOrder(Table table, String querySql) {
        String[] pKeys = table.getPrimaryKey();
        StringBuilder sql = new StringBuilder("select _od from ");
        sql.append("(");
        sql.append("select ").append(StrKit.join(pKeys, ",")).append(",ROW_NUMBER () OVER () AS _od from");
        sql.append("(").append(querySql).append(") _tmp1 ");
        sql.append(") _tmp2 ");
        sql.append("where ");
        for (int i = 0; i < pKeys.length; i++) {
            if (i > 0) {
                sql.append(" and ");
            }
            sql.append('\"').append(pKeys[i]).append("\" = ?");
        }
        return sql.toString();
    }

    private Kv ex;

    public Kv getEx() {
        if (ex == null) {
            ex = Kv.create();
        }
        return ex;
    }

    public M setEx(Object key, Object value) {
        getEx().set(key, value);
        return (M) this;
    }

    public M setExBy(Object exKey, String attr) {
        return setEx(exKey, this.get(attr));
    }

    public M setExBy(Object exKey, String attr, Object defaultValue) {
        return setEx(exKey, this.get(attr, defaultValue));
    }

    public M setExBy(String attr) {
        return setExBy(attr, attr);
    }

}


评论区

zeroabc

2019-12-16 15:02

xxxxx where id>lastId order by id asc limit pageSize 不就好了?

木飘零

2019-12-16 15:58

@zeroabc 主要是我这边很少有直接根据id排序的,一般都是根据各种状态和时间综合排序,甚至有的会根据不通的用户身份,走不同的状态排序规则。。。