com.dexcoder.dal.spring.page.SmartPageSqlHandler Maven / Gradle / Ivy
package com.dexcoder.dal.spring.page;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.Function;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.*;
import com.dexcoder.commons.pager.Pager;
/**
* Created by liyd on 16/6/8.
*/
public class SmartPageSqlHandler extends SimplePageSqlHandler {
private static final List COUNT_ITEM;
private static final Alias TABLE_ALIAS;
static {
COUNT_ITEM = new ArrayList();
COUNT_ITEM.add(new SelectExpressionItem(new Column("count(*)")));
TABLE_ALIAS = new Alias("table_count");
TABLE_ALIAS.setUseAs(false);
}
//缓存已经修改过的sql
private final Map CACHE = new ConcurrentHashMap();
public String getCountSql(String sql, Pager pager, String database) {
//校验是否支持该sql
this.isSupportedSql(sql);
if (CACHE.get(sql) != null) {
return CACHE.get(sql);
}
//解析SQL
Statement stmt;
try {
stmt = CCJSqlParserUtil.parse(sql);
} catch (Throwable e) {
//无法解析的用一般方法返回count语句
String countSql = super.getCountSql(sql, pager, database);
CACHE.put(sql, countSql);
return countSql;
}
Select select = (Select) stmt;
SelectBody selectBody = select.getSelectBody();
//处理body-去order by
processSelectBody(selectBody);
//处理with-去order by
processWithItemsList(select.getWithItemsList());
//处理为count查询
sqlToCount(select);
String result = select.toString();
CACHE.put(sql, result);
return result;
}
/**
* 将sql转换为count查询
*
* @param select
*/
protected void sqlToCount(Select select) {
SelectBody selectBody = select.getSelectBody();
// 是否能简化count查询
if (selectBody instanceof PlainSelect && isSimpleCount((PlainSelect) selectBody)) {
((PlainSelect) selectBody).setSelectItems(COUNT_ITEM);
} else {
PlainSelect plainSelect = new PlainSelect();
SubSelect subSelect = new SubSelect();
subSelect.setSelectBody(selectBody);
subSelect.setAlias(TABLE_ALIAS);
plainSelect.setFromItem(subSelect);
plainSelect.setSelectItems(COUNT_ITEM);
select.setSelectBody(plainSelect);
}
}
/**
* 是否可以用简单的count查询方式
*
* @param select
* @return
*/
protected boolean isSimpleCount(PlainSelect select) {
//包含group by的时候不可以
if (select.getGroupByColumnReferences() != null) {
return false;
}
//包含distinct的时候不可以
if (select.getDistinct() != null) {
return false;
}
for (SelectItem item : select.getSelectItems()) {
//select列中包含参数的时候不可以,否则会引起参数个数错误
if (item.toString().contains("?")) {
return false;
}
//如果查询列中包含函数,也不可以,函数可能会聚合列
if (item instanceof SelectExpressionItem) {
if (((SelectExpressionItem) item).getExpression() instanceof Function) {
return false;
}
}
}
return true;
}
/**
* 处理selectBody去除Order by
*
* @param selectBody
*/
protected void processSelectBody(SelectBody selectBody) {
if (selectBody instanceof PlainSelect) {
processPlainSelect((PlainSelect) selectBody);
} else if (selectBody instanceof WithItem) {
WithItem withItem = (WithItem) selectBody;
if (withItem.getSelectBody() != null) {
processSelectBody(withItem.getSelectBody());
}
} else {
SetOperationList operationList = (SetOperationList) selectBody;
if (operationList.getSelects() != null && operationList.getSelects().size() > 0) {
List plainSelects = operationList.getSelects();
for (SelectBody plainSelect : plainSelects) {
processSelectBody(plainSelect);
}
}
if (!orderByHashParameters(operationList.getOrderByElements())) {
operationList.setOrderByElements(null);
}
}
}
/**
* 处理PlainSelect类型的selectBody
*
* @param plainSelect
*/
protected void processPlainSelect(PlainSelect plainSelect) {
if (!orderByHashParameters(plainSelect.getOrderByElements())) {
plainSelect.setOrderByElements(null);
}
if (plainSelect.getFromItem() != null) {
processFromItem(plainSelect.getFromItem());
}
if (plainSelect.getJoins() != null && plainSelect.getJoins().size() > 0) {
List joins = plainSelect.getJoins();
for (Join join : joins) {
if (join.getRightItem() != null) {
processFromItem(join.getRightItem());
}
}
}
}
/**
* 处理WithItem
*
* @param withItemsList
*/
protected void processWithItemsList(List withItemsList) {
if (withItemsList != null && withItemsList.size() > 0) {
for (WithItem item : withItemsList) {
processSelectBody(item.getSelectBody());
}
}
}
/**
* 处理子查询
*
* @param fromItem
*/
protected void processFromItem(FromItem fromItem) {
if (fromItem instanceof SubJoin) {
SubJoin subJoin = (SubJoin) fromItem;
if (subJoin.getJoin() != null) {
if (subJoin.getJoin().getRightItem() != null) {
processFromItem(subJoin.getJoin().getRightItem());
}
}
if (subJoin.getLeft() != null) {
processFromItem(subJoin.getLeft());
}
} else if (fromItem instanceof SubSelect) {
SubSelect subSelect = (SubSelect) fromItem;
if (subSelect.getSelectBody() != null) {
processSelectBody(subSelect.getSelectBody());
}
} else if (fromItem instanceof ValuesList) {
} else if (fromItem instanceof LateralSubSelect) {
LateralSubSelect lateralSubSelect = (LateralSubSelect) fromItem;
if (lateralSubSelect.getSubSelect() != null) {
SubSelect subSelect = lateralSubSelect.getSubSelect();
if (subSelect.getSelectBody() != null) {
processSelectBody(subSelect.getSelectBody());
}
}
}
//Table时不用处理
}
/**
* 判断Order by是否包含参数,有参数的不能去
*
* @param orderByElements
* @return
*/
protected boolean orderByHashParameters(List orderByElements) {
if (orderByElements == null) {
return false;
}
for (OrderByElement orderByElement : orderByElements) {
if (orderByElement.toString().contains("?")) {
return true;
}
}
return false;
}
protected void isSupportedSql(String sql) {
if (sql.trim().toUpperCase().endsWith("FOR UPDATE")) {
throw new RuntimeException("分页插件不支持包含for update的sql");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy