JFinal使用技巧-数据库查询跳过replaceOrderBy

如题,之前我们有个需求是排序需要按照中文的拼音排序,也就是 ORDER BY CONVERT(c.COURSE_NAME using gbk) 
然后Holder.ORDER_BY_PATTERN.matcher(sql) 是切不全的,
虽然JF内置了public Page<Record> paginateByFullSql(int pageNumber, int pageSize, String totalRowSql, String findSql, Object... paras) {
可自由传入,但是自己切也确实不方便,有ORDER BY性能上也能接受。并且我们是把分页对象封装了的,不想动太多业务代码,最好是加个参数或者加个@Before 就行。。。

那扩展一下吧,

import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;

import java.util.Objects;


public class MyDbKit {
    private static final ThreadLocal<Boolean> paginate_replaceOrderBy = new ThreadLocal();

    private static Boolean setPaginateReplaceOrderBy(Boolean totalRow) {
        Boolean ret = isPaginateReplaceOrderBy();
        paginate_replaceOrderBy.set(totalRow);
        return ret;
    }

    private static void removePaginateReplaceOrderBy() {
        paginate_replaceOrderBy.remove();
    }

    public static Boolean isPaginateReplaceOrderBy() {
        if (paginate_replaceOrderBy.get() == null) {
            return true;
        }
        return paginate_replaceOrderBy.get();
    }

    /**
     * @param replaceOrderBy 是否格掉 Order By
     */
    public static void paginate(Boolean replaceOrderBy, Runnable runnable) {
        Boolean ret = setPaginateReplaceOrderBy(replaceOrderBy);
        try {
            runnable.run();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (Objects.nonNull(ret)) {
                setPaginateReplaceOrderBy(ret);
            } else {
                removePaginateReplaceOrderBy();
            }
        }
    }

    public static class PaginateNotReplaceOrderByInterceptor implements Interceptor {
        public void intercept(Invocation inv) {
            MyDbKit.paginate(false, () -> inv.invoke());
        }
    }

}
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;

public class MyDialect extends MysqlDialect {

    @Override
    public String replaceOrderBy(String sql) {
        return MyDbKit.isPaginateReplaceOrderBy() ? super.replaceOrderBy(sql) : sql;
    }

}

好了,我们使用的MySQL,其他数据库看情况是否可携带OrderBy执行,就继承对应的类。

配置

ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
arp.setDialect(new MyDialect());


使用:在需要跳过ORDER BY的Action上加个@Before即可

@Before(MyDbKit.PaginateNotReplaceOrderByInterceptor.class)
public void index() {
    xxxx
}


OK分享完了

xixi

评论区

JFinal

2022-03-01 20:47

这种方法非常省事, order by 在 mysql 下切换也是可以执行的,在有些数据库必须要去除 order by

点赞 + 收藏

杜福忠

2022-03-02 10:08

@JFinal 昂,明白了,还以为只是为了性能优化了,修改一下帖子

fmpoffice

2022-03-03 11:49

膜拜大佬

热门分享

扫码入社