/** * Copyright (c) 2011-2020, hubin (jobob@qq.com). * <p> * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.baomidou.mybatisplus.toolkit; import java.util.ArrayList; import java.util.List; import com.baomidou.mybatisplus.entity.CountOptimize; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.Function; import net.sf.jsqlparser.expression.LongValue; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.select.Distinct; import net.sf.jsqlparser.statement.select.OrderByElement; import net.sf.jsqlparser.statement.select.PlainSelect; import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.statement.select.SelectExpressionItem; import net.sf.jsqlparser.statement.select.SelectItem; /** * <p> * JsqlParserUtils工具类 * </p> * * @author Caratacus * @Date 2016-11-30 */ public class JsqlParserUtils { private static List<SelectItem> countSelectItem = null; /** * jsqlparser方式获取select的count语句 * * @param originalSql * selectSQL * @return */ public static CountOptimize jsqlparserCount(CountOptimize countOptimize, String originalSql) { String sqlCount; try { Select selectStatement = (Select) CCJSqlParserUtil.parse(originalSql); PlainSelect plainSelect = (PlainSelect) selectStatement.getSelectBody(); Distinct distinct = plainSelect.getDistinct(); List<Expression> groupBy = plainSelect.getGroupByColumnReferences(); // 优化Order by List<OrderByElement> orderBy = plainSelect.getOrderByElements(); // 添加包含groupby 不去除orderby if (CollectionUtils.isEmpty(groupBy) && CollectionUtils.isNotEmpty(orderBy)) { plainSelect.setOrderByElements(null); countOptimize.setOrderBy(false); } // 包含 distinct、groupBy不优化 if (distinct != null || CollectionUtils.isNotEmpty(groupBy)) { sqlCount = String.format(SqlUtils.SQL_BASE_COUNT, selectStatement.toString()); countOptimize.setCountSQL(sqlCount); return countOptimize; } List<SelectItem> selectCount = countSelectItem(); plainSelect.setSelectItems(selectCount); sqlCount = selectStatement.toString(); } catch (Exception e) { sqlCount = String.format(SqlUtils.SQL_BASE_COUNT, originalSql); } countOptimize.setCountSQL(sqlCount); return countOptimize; } /** * 获取jsqlparser中count的SelectItem * * @return */ private static List<SelectItem> countSelectItem() { if (CollectionUtils.isNotEmpty(countSelectItem)) { return countSelectItem; } Function function = new Function(); function.setName("COUNT"); List<Expression> expressions = new ArrayList<>(); LongValue longValue = new LongValue(1); ExpressionList expressionList = new ExpressionList(); expressions.add(longValue); expressionList.setExpressions(expressions); function.setParameters(expressionList); countSelectItem = new ArrayList<>(); SelectExpressionItem selectExpressionItem = new SelectExpressionItem(function); countSelectItem.add(selectExpressionItem); return countSelectItem; } }