Java中通用去除Order By

背景

公司有一个分页的后台组件,为了方便开发人员使用,在让开发人员传分页语句时候,不需要传入求总数的sql语句,那么这样就会有个埋伏,当查询语句时普通查询语句时没有问题,如果查询语句是带有排序的语句,并且sql数据量相对较大的情况下,会在本身查询时不慢,但是在求总数时特别慢。

那么解决上述问题一共有几种办法。

  1. 把分页求总数的语句给单独起个属性给暴露给开发人员。(这样,开发人员的复杂性就大了)
  2. 利用字符串判断order by 的位置,然后截取,(如何保证sql不被截取错误)
  3. 用正则表达式去除最后面的Order By sql子句(多个子查询潜逃的情况下,可能会被删除,导致执行错误)
  4. 解析sql语法,只去除最外层sql的order by,可用工具有(JSqlParser,Apache Calcite,JavaCC,druid)

最后采用第四种方案处理这个问题,下面分别解释各个sql解析工具的利弊。

工具描述优点缺点厂商
JSqlParser基于JavaCC实现的sql解析工具支持多数据库,独立部分数据库支持得不是很好
Apache Calcite基于Javacc实现的Sql解析工具支持多数据库,独立apache顶级开源项目
druid国内阿里巴巴开源的数据库连接池。其中包含的有sql解析的工具支持语言多,解析的AST树复杂跟数据库连接池耦合在一起,无法拆开使用阿里巴巴
JavaCC语法解析工具
antlr语法解析工具

使用jsqlparse处理的方式,去除最外层sql包含的order by

CCJSqlParserManager pm = new CCJSqlParserManager();
		String countquerySql = querysql;
		try{
			Statement parse = pm.parse(new StringReader(querysql));
			Select noOrderSelect = (Select)parse;
			SelectBody selectBody = noOrderSelect.getSelectBody();
			PlainSelect setOperationList = (PlainSelect)selectBody;
			if (null!=setOperationList.getOrderByElements()){
				setOperationList.setOrderByElements(null);
			};
			countquerySql = noOrderSelect.toString();
			if(logger.isDebugEnabled()){
				logger.debug("Delete the last order by statement with jsqlparse , sql:{}",countquerySql);
			}
		}catch (JSQLParserException e){
			//throw new DbException("sql parse is err (remove count order by) , sql is : "+querysql);
			logger.warn("sql parse is err(remove count order by) origin sql:{}, fix sql:{}",querysql,countquerySql);
			countquerySql = querysql;
		}

使用druid去除最外层sql中的order by ,后面补充

使用Calcite去除最外层sql的的orderby,后面补充

最后采用jsqlparse,原因是之前采用过

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值