jsqlparser描述:

JSqlParser 解析 SQL 语句并将其转换为 Java 类的层次结构。基本上的sql关键字和函数都可以被jsqlparser解析成对象层层包装。

实现的功能:

基础sql查询,条件查询,字段和表得别名,排序,分组,聚合,case when,基本上都是有得。

我的使用场景:

将一个表和字段不是数据库直接查询的表字段,进行通过jsqlparser来转换成elasticsearch中存储的表和字段进行到openlokeng中进行查询

界面输入:

openlookeng 执行:

举例:

首先在页面输入:SELECT t1.公司名称 from gxb.新规则表5 t1
然后通过解析后:SELECT eas_file_197_1_1_1_1_1_2.column2 FROM eas_file_197_1_1_1_1_1_2

解析对象:


自定义函数:

实际使用:

@Injectprivate Metadata metadata;@Injectprivate DataManager dataManager;@Injectprivate TimeSource timeSource;@Injectprivate Logger log;@Injectprivate DataServiceConfig dataServiceConfig;@Injectprivate CustomConfig customConfig;private static final String CLASSIFY_NAME = "classifyName";private static final String TABLE_NAME = "tableName";private static final String TABLE_ALIAS = "tableAlias";private static final String STATUS = "status";private static final String SUCCESS = "success";private static final String FAILED = "failed";@Overridepublic Object execute(String sql, UserExt userExt, Page page){if(Objects.isNull(page)) page = new Page();long startTime = timeSource.currentTimeMillis();String operateResult = "执行成功";Map<String, Object> resultObj = new HashMap<>();List<HashMap<String, Object>> jsonArray = new ArrayList<>();try {Statements stmts = parseStatements(sql);Page finalPage = page;stmts.getStatements().forEach(stmt -> {if (stmt instanceof Select) {executeSelect(stmt,finalPage,jsonArray);}});resultObj.put("data", jsonArray);resultObj.put(STATUS, SUCCESS);} catch (JSQLParserException e) {operateResult = "执行失败,输入SQL语法错误";resultObj.put(STATUS, FAILED);throw new SQLParserException("输入SQL语法错误",e);}catch (Exception e){operateResult = "执行失败,接口处理异常";resultObj.put(STATUS, FAILED);throw new SQLParserException("接口处理异常",e);}finally {saveOperateHistory(sql, userExt, startTime, operateResult);}return resultObj;}/*** 具体执行 select 解析后返回 jsonArray 对象* @param stmt* @param finalPage* @param jsonArray*/private void executeSelect(Statement stmt, Page finalPage, List<HashMap<String, Object>> jsonArray) {Map<String, Object> tempMap = parseSelectSql((Select) stmt, finalPage);String paramSql = formatSql((String) tempMap.get("sql"));List<SqlStatementEasTableVo> tables = (List<SqlStatementEasTableVo>) tempMap.get("tables");Map<String, String> config = getDataServiceConfig(tables.get(0));String database = config.get("database");String schemaName = config.get("schema");log.info("数据服务入参:");log.info("sql: {}", paramSql);log.info("database: {} | schemaName: {}", database, schemaName);if(Objects.isNull(database) || Objects.isNull(schemaName) ){throw new SQLParserException("database 或 schema 为空 ");}Page resultPage = (Page) tempMap.get("page");RunQueryResponse response = invokeDataService(database, schemaName, paramSql);if(resultPage.isSelectAll()){resultPage.setTotalCount(response.getTotal().longValue());resultPage.setPageCount(getPageCount(response.getTotal().longValue(), finalPage.getPageSize()));}resultPage.setList(response.getResult());HashMap<String, Object> objHashMap = new HashMap<>();tempMap.put("page", resultPage);objHashMap.put("metas", tempMap);jsonArray.add(objHashMap);}private Map<String, String> getDataServiceConfig(SqlStatementEasTableVo entity) {EasTable easTable = getEasTable(entity.getClassifyName(), entity.getName());Map<String,String> resultMap = new HashMap<>();if(Objects.nonNull(easTable)){String database = Objects.isNull(easTable.getDatabase()) ? "" : easTable.getDatabase().getAlias();String schema = easTable.getSchema().getSchema().getName();resultMap.put("database", database);resultMap.put("schema", schema);}return resultMap;}private List<EasColumn> parseSelectItem(PlainSelect selectBody, List<Map<String, String>> tableItems) {List<EasColumn> resultColumn = new ArrayList<>();selectBody.getSelectItems().forEach(s -> s.accept(new SelectItemVisitorAdapter() {@Overridepublic void visit(AllColumns columns) {Map<String, String> tableMap = Objects.nonNull(tableItems.get(0)) ? tableItems.get(0) : new HashMap<>();EasTable easTable = getEasTable(tableMap.get(CLASSIFY_NAME), tableMap.get(TABLE_NAME));if (Objects.isNull(easTable)) return;List<SelectItem> list = new ArrayList<>();easTable.getColumn().forEach(c -> {Column column = initColumn(easTable.getTable().getName(), c.getColumn().getName());SelectExpressionItem selectExpressionItem = new SelectExpressionItem(column);list.add(selectExpressionItem);resultColumn.add(c);});selectBody.setSelectItems(list);}@Overridepublic void visit(AllTableColumns columns) {String name = columns.getTable().getName();Map<String, String> tableMap = tableItems.stream().filter(t -> StringUtils.equals(name, t.get(TABLE_ALIAS))).findFirst().orElse(new HashMap<>());EasTable easTable = getEasTable(tableMap.get(CLASSIFY_NAME), tableMap.get(TABLE_NAME));if (Objects.isNull(easTable)) return;List<SelectItem> list = new ArrayList<>();easTable.getColumn().forEach(c -> {Column column = initColumn(easTable.getTable().getName(), c.getColumn().getName());SelectExpressionItem selectExpressionItem = new SelectExpressionItem(column);list.add(selectExpressionItem);resultColumn.add(c);});selectBody.setSelectItems(list);}@Overridepublic void visit(SelectExpressionItem item) {//如果是条件查询的case,否则默认为字段switch (item.getExpression().getClass().getName()){case "net.sf.jsqlparser.expression.CaseExpression":caseExpression(item,tableItems,resultColumn);break;case "net.sf.jsqlparser.expression.Function":functionExpression(item,tableItems,resultColumn);break;default:basicExpression(item,tableItems,resultColumn);break;}}}));return resultColumn;}/*** 带有条件的 查询字段的进行拼接转换* @param item* @param tableItems* @param resultColumn*/private void caseExpression(SelectExpressionItem item,List<Map<String, String>> tableItems,List<EasColumn> resultColumn) {Column switchExpression = ((CaseExpression) item.getExpression()).getSwitchExpression(Column.class);EasColumn easColumn;//这里要处理 ,分情况, 如果是 没有switch 的时候if(Objects.isNull(switchExpression)){easColumn =noHaveSwitchExpression(item,tableItems);}else{easColumn =haveSwitchExpression(item,tableItems,switchExpression);}if (Objects.isNull(easColumn)) return ;//这里构造一个新的自定义的别名 column 给前端,为了展示EasColumn newEasColumn=customAlias(item,easColumn.getColumn().getName(),DimensionType.BUSINESS);resultColumn.add(newEasColumn);}/*** 没有switchExpression 表示*  case when  列名=值 then  ''*/private EasColumn noHaveSwitchExpression(SelectExpressionItem item, List<Map<String, String>> tableItems) {List<WhenClause> whenClauseList=new ArrayList<>();EasColumn easColumn = null;for (WhenClause i : ((CaseExpression) item.getExpression()).getWhenClauses()) {Column left = ((EqualsTo) i.getWhenExpression()).getLeftExpression(Column.class);Map<String, String> leftTableMap = tableItems.stream().filter(t -> StringUtils.equals(left.getTable().getName(), t.get(TABLE_ALIAS))).findFirst().orElse(new HashMap<>());//大于0 表示 匹配到别名 t1, 否则就用默认的 文件夹.表名.列名EasTable easTable;if(leftTableMap.size()>0){//  on  左边  转换的表名easTable = getEasTable(leftTableMap.get(CLASSIFY_NAME), leftTableMap.get(TABLE_NAME));}else{easTable = getEasTable(left.getTable().getSchemaName(), left.getTable().getName());}if (Objects.isNull(easTable)) return null;EasColumn leftColumn = easTable.getColumn().stream().filter(c -> StringUtils.equals(left.getColumnName(), c.getName())).findFirst().orElse(null);if (Objects.isNull(leftColumn)) return null;EasTable finalEasTable1 = easTable;WhenClause whenClause= i;BinaryExpression onExpression = new EqualsTo();onExpression.setLeftExpression(new Column(new Table(finalEasTable1.getTable().getName()),leftColumn.getColumn().getName()));onExpression.setRightExpression(((EqualsTo) i.getWhenExpression()).getRightExpression());whenClause.setWhenExpression(onExpression);whenClauseList.add(whenClause);//替换原有的case when 中文表名 -> case when es表名((CaseExpression) item.getExpression()).setWhenClauses(whenClauseList);easColumn = easTable.getColumn().stream().filter(c -> StringUtils.equals(left.getColumnName(), c.getName())).findFirst().orElse(null);if (Objects.isNull(easColumn)) return null;}return easColumn;}/*** 有switchExpression 表示*  case 列名  when 值 then  ''*/private EasColumn haveSwitchExpression(SelectExpressionItem item, List<Map<String, String>> tableItems, Column switchExpression) {Map<String,Object> map= Collections.unmodifiableMap(getNewColumn(tableItems, switchExpression));//重新赋值给 函数表达式EasColumn easColumn=(EasColumn)map.get("easColumn");EasTable easTable=(EasTable)map.get("easTable");//将获取转化后的表.列,重新赋值给 switchExpression对象EasTable finalEasTable = easTable;item.getExpression().accept(new ExpressionVisitorAdapter(){@Overridepublic void visit(CaseExpression caseExpression) {caseExpression.setSwitchExpression(initColumn(finalEasTable.getTable().getName(), easColumn.getColumn().getName()));}});return easColumn;}/*** 带有条件的 查询字段的进行拼接转换* @param item* @param tableItems* @param resultColumn*/private void functionExpression(SelectExpressionItem item,List<Map<String, String>> tableItems,List<EasColumn> resultColumn) {List<Expression> expressions=new ArrayList<>();ExpressionList functionExpressions= ((net.sf.jsqlparser.expression.Function)item.getExpression()).getParameters();if(Objects.nonNull(functionExpressions)){//这里表示的 是 count + 具体字段List<Expression>  expressionList= functionExpressions.getExpressions();expressionList.forEach(expression -> {//判断是否是自定义日期函数if(((net.sf.jsqlparser.expression.Function)item.getExpression()).getMultipartName().get(0).equals(customConfig.getDoTimeFunction())){functionItem(expression,tableItems,expressions,item,resultColumn,expressionList.get(1));}else{functionItem(expression,tableItems,expressions,item,resultColumn,null);}});}else{//这里表示 的是 count (*)//这里构造一个新的自定义的别名 column 给前端,为了展示EasColumn newEasColumn=customAlias(item,item.getAlias().getName(),DimensionType.BUSINESS);resultColumn.add(newEasColumn);}}/*** 函数 count + 具体字段*/private void functionItem(Expression expression, List<Map<String, String>> tableItems, List<Expression> expressions, SelectExpressionItem item, List<EasColumn> resultColumn,Expression value) {if(expression instanceof Column){Column functionExpression = (Column) expression;item.getExpression().accept(new ExpressionVisitorAdapter(){@Overridepublic void visit(ExpressionList expression) {Map<String,Object> map= Collections.unmodifiableMap(getNewColumn(tableItems, functionExpression));Column newColumn=(Column) map.get("newColumn");EasColumn easColumn =(EasColumn) map.get("easColumn");//重新赋值给 函数表达式expressions.add(newColumn);expression.setExpressions(expressions);//这里构造一个新的自定义的别名 column 给前端,为了展示EasColumn newEasColumn=customAlias(item,easColumn.getColumn().getName(),easColumn.getDimensionType());resultColumn.add(newEasColumn);net.sf.jsqlparser.expression.Function function=((net.sf.jsqlparser.expression.Function)item.getExpression());List<String> customerFunctionNames=function.getMultipartName();//这里要判断下自定义时间函数for(String customerFunctionName:customerFunctionNames) {if (Objects.nonNull(customerFunctionName) &&customerFunctionName.equals(customConfig.getDoTimeFunction())&& Objects.nonNull(value)) {net.sf.jsqlparser.expression.Function expressFunction = ((net.sf.jsqlparser.expression.Function) item.getExpression());expressFunction.setName("from_unixtime");ExpressionList list= customTimeFunction(value, expression);expressFunction.setParameters(list);}}}});}}/*** 自定义时间段分组函数*/private ExpressionList customTimeFunction(Expression value, ExpressionList expression) {//from_unixtime((to_unixtime(eas_file_493_2.column0) / 60 ) * 60)//1.上面已经拼好 eas_file_493_2.column0//2.然后拼 to_unixtime(eas_file_493_2.column0)ExpressionList list=new ExpressionList();//to_unixtimenet.sf.jsqlparser.expression.Function newFunction=new net.sf.jsqlparser.expression.Function();newFunction.setName("to_unixtime");newFunction.setParameters(expression);//3.再拼  to_unixtime(eas_file_493_2.column0) / 60Division division=new Division();division.setLeftExpression(newFunction);division.setRightExpression(value);//((to_unixtime(eas_file_493_2.column0) / 60 )ExpressionList expressionList1=new ExpressionList();expressionList1.addExpressions(division);net.sf.jsqlparser.expression.Function newFunction2=new net.sf.jsqlparser.expression.Function();newFunction2.setName("");newFunction2.setParameters(expressionList1);//4.最后拼  (to_unixtime(eas_file_493_2.column0) / 60 ) * 60Multiplication multiplication2=new Multiplication();multiplication2.setLeftExpression(newFunction2);multiplication2.setRightExpression(value);list.addExpressions(multiplication2);return list;}/*** 根据 是否有别名,执行对应的操作。*/private  void basicExpression( SelectExpressionItem item,List<Map<String, String>> tableItems,List<EasColumn>  resultColumn){Column expression = item.getExpression(Column.class);Map<String,Object> map= Collections.unmodifiableMap(getNewColumn(tableItems, expression));//重新赋值给 函数表达式EasColumn easColumn=(EasColumn)map.get("easColumn");EasTable easTable=(EasTable)map.get("easTable");//这里构造一个新的自定义的别名 column 给前端,为了展示EasColumn newEasColumn=customAlias(item,easColumn.getColumn().getName(),easColumn.getDimensionType());resultColumn.add(newEasColumn);item.setExpression(initColumn(easTable.getTable().getName(), easColumn.getColumn().getName()));}/*** 自定义字段别名, COLUMN AS ""* @param item* @param easColumnName* @param dimensionType* @return*/private static EasColumn customAlias (SelectExpressionItem item,String easColumnName,DimensionType dimensionType){//这里构造一个新的自定义的别名 column 给前端,为了展示EasColumn newEasColumn=new EasColumn();String tempName;if(item.getAlias() ==null ){tempName=easColumnName;}else{tempName=item.getAlias().getName().replace("\"", "");}newEasColumn.setOriginalName(tempName);newEasColumn.setName(tempName);newEasColumn.setDimensionType(dimensionType);cn.com.dataocean.metadata.entity.Column column=new cn.com.dataocean.metadata.entity.Column();column.setName(tempName);newEasColumn.setColumn(column);return newEasColumn;}private Column initColumn(String tableName, String columnName ){Table table = new Table(tableName);return new Column(table, columnName);}/*** 分组 group by 处理* @param selectBody* @param tableItems*/private void parseGroupBy(PlainSelect selectBody, List<Map<String, String>> tableItems) {if (Objects.nonNull(selectBody.getGroupBy())) {List<Expression> expressions=new ArrayList<>();ExpressionList groupByList=selectBody.getGroupBy().getGroupByExpressionList();groupByList.getExpressions().forEach(expression -> groupByList.accept(new ExpressionVisitorAdapter(){@Overridepublic void visit(ExpressionList express) {groupBy(expression,tableItems,expressions,express);}}));}}/*** 区别 是否有自定义时间段 函数,否则为普通group by*/private void groupBy(Expression expression, List<Map<String, String>> tableItems, List<Expression> expressions, ExpressionList express){//这里要判断下自定义时间函数if((expression instanceof Column)){Column group = (Column) expression;Map<String,Object> map= Collections.unmodifiableMap(getNewColumn(tableItems, group));//重新赋值给 函数表达式expressions.add((Column) map.get("newColumn"));express.setExpressions(expressions);}else{net.sf.jsqlparser.expression.Function function= (net.sf.jsqlparser.expression.Function) expression;Expression value=function.getParameters().getExpressions().get(1);function.getParameters().getExpressions().forEach(expression1 -> {if(!(expression1 instanceof Column)){return ;}Column functionExpression = (Column) expression1;expression.accept(new ExpressionVisitorAdapter(){@Overridepublic void visit(ExpressionList expression) {Map<String,Object> map= Collections.unmodifiableMap(getNewColumn(tableItems, functionExpression));//重新赋值给 函数表达式expressions.add((Column) map.get("newColumn"));expression.setExpressions(expressions);//自定义函数 重新赋值List<String> customerFunctionNames=function.getMultipartName();//这里要判断下自定义时间函数for(String customerFunctionName:customerFunctionNames) {if (Objects.nonNull(customerFunctionName) && customerFunctionName.equals(customConfig.getDoTimeFunction()) && Objects.nonNull(value)) {function.setName("from_unixtime");ExpressionList expressionList=customTimeFunction(value, expression);function.setParameters(expressionList);}}}});});}}/*** 获取重新拼接的 table 和 column* @param tableItems* @param functionExpression* @return*/private Map<String,Object> getNewColumn(List<Map<String, String>> tableItems, Column functionExpression) {Map<String, String> tableMap = tableItems.stream().filter(t -> StringUtils.equals(functionExpression.getTable().getName(), t.get(TABLE_ALIAS))).findFirst().orElse(new HashMap<>());EasTable easTable;//大于0 表示 匹配到别名 t1, 否则就用默认的 文件夹.表名.列名if(tableMap.size()>0){easTable = getEasTable(tableMap.get(CLASSIFY_NAME), tableMap.get(TABLE_NAME));}else{easTable = getEasTable(functionExpression.getTable().getSchemaName(), functionExpression.getTable().getName());}if (Objects.isNull(easTable)) return null;EasColumn easColumn = easTable.getColumn().stream().filter(c -> StringUtils.equals(functionExpression.getColumnName(), c.getName())).findFirst().orElse(null);if (Objects.isNull(easColumn)) return null;Column newColumn=initColumn(easTable.getTable().getName(), easColumn.getColumn().getName());Map<String,Object> map=new HashMap();map.put("easTable",easTable);map.put("easColumn",easColumn);map.put("newColumn",newColumn);return map;}private void parseHaving(PlainSelect selectBody, List<Map<String, String>> tableItems) {if (Objects.nonNull(selectBody.getHaving())) {selectBody.getHaving().accept(new ExpressionVisitorAdapter(){@Overridepublic void visit(ExpressionList expression) {List<Expression> expressions=new ArrayList<>();List<Expression> columnList=expression.getExpressions();columnList.forEach(tempColumn->{Column having = (Column) tempColumn;Map<String,Object> map= getNewColumn(tableItems,having);//重新赋值给 函数表达式EasColumn easColumn=(EasColumn)map.get("easColumn");EasTable easTable=(EasTable)map.get("easTable");Column newColumn=initColumn(easTable.getTable().getName(), easColumn.getColumn().getName());//重新赋值给 函数表达式expressions.add(newColumn);expression.setExpressions(expressions);});}});}}private Page parseLimit(PlainSelect selectBody, Page page) {Page resultPage = new Page();long limit = page.getPageSize();long offset = (page.getCurrentPage()-1)*limit < 0 ? 0 : (page.getCurrentPage()-1)*limit;if (Objects.isNull(selectBody.getLimit())) {resultPage.setSelectAll(true);}else{long total = selectBody.getLimit().getRowCount(LongValue.class).getValue(); //sql语句中的limit参数resultPage.setSelectAll(false);resultPage.setTotalCount(total);resultPage.setPageCount(getPageCount(total,limit));if(total < offset){limit = 0;}else if(total-offset < limit){limit = total-offset;}}selectBody.setLimit(new Limit().withRowCount(new LongValue(limit)));selectBody.setOffset(new Offset().withOffset(offset));resultPage.setCurrentPage(page.getCurrentPage());resultPage.setLimit(limit);resultPage.setOffset(offset);return resultPage;}private void parseWhere(PlainSelect selectBody,List<Map<String, String>> tableMap) {if (Objects.nonNull(selectBody.getWhere())) {selectBody.getWhere().accept(new ExpressionVisitorAdapter() {@Overridepublic void visit(Column column) {EasTable easTable;//大于0 表示 匹配到别名 t1, 否则就用默认的 文件夹.表名.列名if(!tableMap.isEmpty()){easTable = getEasTable(tableMap.get(0).get(CLASSIFY_NAME), tableMap.get(0).get(TABLE_NAME));}else{easTable = getEasTable(column.getTable().getSchemaName(), column.getTable().getName());}if (Objects.isNull(easTable)) return;EasColumn easColumn = easTable.getColumn().stream().filter(c -> StringUtils.equals(column.getColumnName(), c.getName())).findFirst().orElse(null);if (Objects.isNull(easColumn)) return;column.setColumnName(easColumn.getColumn().getName());Table table = new Table(easTable.getTable().getName());column.setTable(table);}});}}private Map<String, String> parseFromItem(PlainSelect selectBody) {Map<String, String> fromItemMap = new HashMap<>();selectBody.getFromItem().accept(new FromItemVisitorAdapter() {@Overridepublic void visit(Table table) {fromItemMap.put(CLASSIFY_NAME, table.getSchemaName());fromItemMap.put(TABLE_NAME, table.getName());fromItemMap.put(TABLE_ALIAS, Objects.nonNull(table.getAlias()) ? table.getAlias().getName() : null);EasTable easTable = getEasTable(table.getSchemaName(), table.getName());if (Objects.isNull(easTable)) return;table.setName(easTable.getTable().getName());table.setAlias(null);table.setSchemaName(null);}});return fromItemMap;}/*** 解析连表查询的表** @param selectBody* @return*/private List<Map<String, String>> parseJoinItem(PlainSelect selectBody, List<Map<String, String>> tableItems) {if (Objects.nonNull(selectBody.getJoins())) {selectBody.getJoins().forEach(j -> {Table rightItem = j.getRightItem(Table.class);Map<String, String> joinItemMap = new HashMap<>();if (rightItem instanceof Table) {rightItem.accept(new FromItemVisitorAdapter() {@Overridepublic void visit(Table table) {joinItemMap.put(CLASSIFY_NAME, table.getSchemaName());joinItemMap.put(TABLE_NAME, table.getName());joinItemMap.put(TABLE_ALIAS, Objects.nonNull(table.getAlias()) ? table.getAlias().getName() : null);}});tableItems.add(joinItemMap);}EasTable easTable = getEasTable(rightItem.getSchemaName(), rightItem.getName());j.setRightItem(new Table(easTable.getTable().getName()));Expression onColumn= j.getOnExpression();if(onColumn!=null){//拼接join 后 的on 条件j.setOnExpression(getNewOnExpression(onColumn,tableItems));}});}return tableItems;}private BinaryExpression getNewOnExpression(Expression onColumn,List<Map<String, String>> tableItems) {Column left=((EqualsTo) onColumn).getLeftExpression(Column.class);Column right=((EqualsTo) onColumn).getRightExpression(Column.class);BinaryExpression onExpression = new EqualsTo();Map<String, String> leftTableMap = tableItems.stream().filter(t -> StringUtils.equals(left.getTable().getName(), t.get(TABLE_ALIAS))).findFirst().orElse(new HashMap<>());Map<String, String> rightTableMap = tableItems.stream().filter(t -> StringUtils.equals(right.getTable().getName(), t.get(TABLE_ALIAS))).findFirst().orElse(new HashMap<>());EasTable leftEasTable ;EasTable rightEasTable;//大于0 表示 匹配到别名 t1, 否则就用默认的 文件夹.表名.列名if(leftTableMap.size()>0 && rightTableMap.size()>0){//  on  左边  =  右边leftEasTable = getEasTable(leftTableMap.get(CLASSIFY_NAME), leftTableMap.get(TABLE_NAME));rightEasTable = getEasTable(rightTableMap.get(CLASSIFY_NAME), rightTableMap.get(TABLE_NAME));}else{rightEasTable = getEasTable(right.getTable().getSchemaName(), right.getTable().getName());leftEasTable = getEasTable(left.getTable().getSchemaName(), left.getTable().getName());}if (Objects.isNull(leftEasTable)) return null;EasColumn leftColumn = leftEasTable.getColumn().stream().filter(c -> StringUtils.equals(left.getColumnName(), c.getName())).findFirst().orElse(null);if (Objects.isNull(leftColumn)) return null;if (Objects.isNull(rightEasTable)) return null;EasColumn rightColumn = rightEasTable.getColumn().stream().filter(c -> StringUtils.equals(right.getColumnName(), c.getName())).findFirst().orElse(null);if (Objects.isNull(rightColumn)) return null;onExpression.setLeftExpression(new Column(new Table(leftEasTable.getTable().getName()),leftColumn.getColumn().getName()));onExpression.setRightExpression(new Column(new Table(rightEasTable.getTable().getName()),rightColumn.getColumn().getName()));return onExpression;}/*** 排序* @param selectBody* @param tableItems*/private void parseOrderBy(PlainSelect selectBody, List<Map<String, String>> tableItems) {if (Objects.nonNull(selectBody.getOrderByElements())) {selectBody.getOrderByElements().forEach(item->{List<Expression> expressions=new ArrayList<>();if(item.getExpression() instanceof Column) {orderByItem(item,tableItems);}else{ExpressionList functionExpressions = ((net.sf.jsqlparser.expression.Function) item.getExpression()).getParameters();List<Expression> expressionList = functionExpressions.getExpressions();expressionList.forEach(expression ->orderByFunction(expression,item,tableItems,expressions));}});}}/*** 根据原字段排序* @param item* @param tableItems*/private void orderByItem(OrderByElement item, List<Map<String, String>> tableItems) {Column expression = item.getExpression(Column.class);Map<String,Object> map= Collections.unmodifiableMap(getNewColumn(tableItems, expression));//重新赋值给 函数表达式EasColumn easColumn=(EasColumn)map.get("easColumn");EasTable easTable=(EasTable)map.get("easTable");item.setExpression(initColumn(easTable.getTable().getName(), easColumn.getColumn().getName()));}/*** 根据 聚合字段排序* @param expression* @param item* @param tableItems* @param expressions*/private void orderByFunction(Expression expression, OrderByElement item, List<Map<String, String>> tableItems, List<Expression> expressions) {Column functionExpression = (Column) expression;item.getExpression().accept(new ExpressionVisitorAdapter() {@Overridepublic void visit(ExpressionList expression) {Map<String,Object> map= Collections.unmodifiableMap(getNewColumn(tableItems, functionExpression));//重新赋值给 函数表达式EasColumn easColumn=(EasColumn)map.get("easColumn");EasTable easTable=(EasTable)map.get("easTable");Column newColumn=initColumn(easTable.getTable().getName(), easColumn.getColumn().getName());//重新赋值给 函数表达式expressions.add(newColumn);expression.setExpressions(expressions);}});}public EasTable getEasTable(String classifyName, String tableName) {return dataManager.load(EasTable.class).query("select e from eas$EasTable e " +"where e.name = :name " +"and e.classify.classifyName = :classify").parameter("name", tableName).parameter("classify", classifyName).view("easTable-view-sqlAssociate").optional().orElse(null);}/*** 解析select sql语句** @param stmt* @return*/public Map<String, Object> parseSelectSql(Select stmt, Page page) {Map<String, Object> map = new HashMap<>();PlainSelect selectBody = (PlainSelect) stmt.getSelectBody();List<Map<String, String>> tableItems = new ArrayList<>();tableItems.add(parseFromItem(selectBody));tableItems.addAll(parseJoinItem(selectBody,tableItems));List<EasTable> resultTables = new ArrayList<>();tableItems.forEach(t -> {EasTable easTable = getEasTable(t.get(CLASSIFY_NAME), t.get(TABLE_NAME));resultTables.add(easTable);resultTables.stream().filter(distinctByKey(BaseUuidEntity::getId));});List<EasColumn> resultColumn = parseSelectItem(selectBody, tableItems);parseWhere(selectBody,tableItems);parseGroupBy(selectBody,tableItems);parseHaving(selectBody,tableItems);parseOrderBy(selectBody,tableItems);Page resultPage = parseLimit(selectBody,page);map.put("sql", stmt.toString());map.put("column", simplifyEasColumn(resultColumn));map.put("tables", translateToTableVo(resultTables));map.put("id", UUID.randomUUID());map.put("page",resultPage);return map;}private List<EasColumn> simplifyEasColumn(List<EasColumn> columns){columns.forEach(c -> c.setTable(null));return columns;}private List<SqlStatementEasTableVo> translateToTableVo(List<EasTable> resultTables) {List<SqlStatementEasTableVo> resultTableVos = new ArrayList<>();resultTables.forEach(t -> {if(Objects.nonNull(t)){SqlStatementEasTableVo sqlStatementEasTableVo = new SqlStatementEasTableVo();sqlStatementEasTableVo.setId(t.getId());sqlStatementEasTableVo.setName(t.getName());sqlStatementEasTableVo.setDescription(t.getDescription());sqlStatementEasTableVo.setVersion(t.getVersion());sqlStatementEasTableVo.setClassifyId(Objects.isNull(t.getClassify()) ? null : t.getClassify().getId());sqlStatementEasTableVo.setClassifyName(Objects.isNull(t.getClassify()) ? null : t.getClassify().getClassifyName());sqlStatementEasTableVo.setDatabaseId(Objects.isNull(t.getDatabase()) ? null : t.getDatabase().getId());resultTableVos.add(sqlStatementEasTableVo);}});return resultTableVos;}/*** 使用jsqlparser把SQL解析成对象** @param sql* @return* @throws JSQLParserException*/public Statements parseStatements(String sql) throws JSQLParserException {return CCJSqlParserUtil.parseStatements(sql);}private RunQueryResponse invokeDataService(String database, String schema, String paramSql) {return QueryRunner.newInstance().url(dataServiceConfig.getDataServiceUrl()).database(database).schema(schema).statement(paramSql).run();}/*** 保存SQL执行历史** @param sql* @param userExt* @param startTime* @return*/public EasSqlStatementOperateHistory saveOperateHistory(String sql, UserExt userExt, long startTime, String operateResult) {long endTime = timeSource.currentTimeMillis();String elapsedTime = endTime - startTime + "";EasSqlStatementOperateHistory easSqlStatementOperateHistory = metadata.create(EasSqlStatementOperateHistory.class);easSqlStatementOperateHistory.setOperator(userExt);easSqlStatementOperateHistory.setSqlStatement(sql);easSqlStatementOperateHistory.setElapsedTime(elapsedTime);easSqlStatementOperateHistory.setOperateResult(operateResult);easSqlStatementOperateHistory.setOperateTime(timeSource.currentTimestamp());dataManager.commit(easSqlStatementOperateHistory);return easSqlStatementOperateHistory;}/*** 获取SQL查询联想内容** @return*/@Overridepublic String getAssociateContent() {long startTime = timeSource.currentTimeMillis();List<EasTable> easTables = dataManager.load(EasTable.class).query("select e from eas$EasTable e where e.tableType = :type1 or e.tableType = :type2 and e.classify.id is not null ").view("easTable-view-sqlAssociate")
//                .parameter("type1",TableType.DATAFRAME.getId())
//                .parameter("type2",TableType.ESDATAFRAME.getId()).parameter("type1","工作表").parameter("type2","ES工作表").list();long time2 = timeSource.currentTimeMillis();log.info("查询easTable耗时:{} ms",time2-startTime);JSONObject resultJson = new JSONObject();easTables.forEach(easTable -> {List<EasColumn> easColumns = dataManager.load(EasColumn.class).query("select e from eas$EasColumn e where e.table.id = :table").parameter("table",easTable.getId()).list();String classifyName = easTable.getClassify().getClassifyName();String name = easTable.getName();Object[] objects = easColumns.stream().map(EasColumn::getName).toArray();resultJson.put(classifyName + "." + name, objects);});long time3 = timeSource.currentTimeMillis();log.info("查询column及拼接耗时:{} ms", time3-time2);return resultJson.toJSONString();}public long getPageCount(Long total, Long pageSize){return (total+pageSize-1)/pageSize;}private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {Map<Object, Boolean> seen = new ConcurrentHashMap<>();return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;}/*** 当前数据服务对SQL格式有着很严格的要求,SQL语句最后必须为空格,且不能带分号* 这里做一些特殊转换* @param sql* @return*/private String formatSql(String sql){sql = sql.trim();if(sql.endsWith(";")){sql = sql.substring(0,sql.length()-1);}return sql.trim()+" ";}}

java使用jsqlparser实现自定义转换相关推荐

  1. Google App Engine for Java下的URL编码转换问题

    URL编码问题 此部分参考英文资料: http://www.blooberry.com/indexdot/html/topics/urlencoding.htm http://www.w3school ...

  2. java 转xml 变成两根下划线_XStream实现xml和java对象之间的互相转换(包括对属性,别名,下划线_的处理),同理JSON也可以...

    首先去官网下载响应JAR包 最少需要两个jar包,一个xstream.jar,一个是xmlpull.jar 首先来看下java对象到xml的转换 package xml; class PhoneNum ...

  3. 怎么在java中创建一个自定义的collector

    文章目录 简介 Collector介绍 自定义Collector 总结 怎么在java中创建一个自定义的collector 简介 在之前的java collectors文章里面,我们讲到了stream ...

  4. c++中的new_怎么在java中创建一个自定义的collector

    简介 在之前的java collectors文章里面,我们讲到了stream的collect方法可以调用Collectors里面的toList()或者toMap()方法,将结果转换为特定的集合类. 今 ...

  5. 使用json-lib进行Java和JSON之间的转换

    转自http://www.cnblogs.com/mailingfeng/archive/2012/01/18/2325707.html 1. json-lib是一个java类库,提供将Java对象, ...

  6. 第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单

    我们来了解一下 自定义菜单创建接口: http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_to ...

  7. java 可以直接当自定义标示符_第2章 Java基本语法.ppt

    <第2章 Java基本语法.ppt>由会员分享,可在线阅读,更多相关<第2章 Java基本语法.ppt(55页珍藏版)>请在人人文库网上搜索. 1.第2章了解Java基本语法, ...

  8. Java Server Faces (JSF)页面转换与验证(二)

    2019独角兽企业重金招聘Python工程师标准>>> 这个案例分析的目的是将一个单字段字符串值转换为一个  PhoneNumber对象.我们将一步一步地完成这个转换过程. 第 1 ...

  9. Java中如何创建自定义的注解学习笔记(MD版)

    概要 Java中如何创建自定义的注解学习笔记(MD版). 博客 博客地址:IT老兵驿站. 前言 记得这篇笔记还是在泉州的龙玲酒店记录的,是一个周六的晚上,坐飞机从上海到泉州,从笔记中能勾起一些旅游的回 ...

最新文章

  1. Eclipse中输入系统变量和运行参数
  2. App in Scala
  3. 集合框架 Queue---ArrayBlockingQueue
  4. php 数组的定义方法,PHP中数组定义的几种方法
  5. mysql十万条数据_2秒内向数据库中插入十万条数据?
  6. matlab两个图共用一个x轴_Matlab Figures (3) —— 叠加作图与多坐标轴
  7. python websocket异步高并发_python – WebSocket聊天异步示例崩溃
  8. python histogram函数_python (ploit2)(histogram)
  9. python数据分析之(4)读写数据文件CSV,EXCEL等
  10. ActiveMQ(一)——JMS、应用场景、关键对象、demo
  11. Java 将PDF转为OFD
  12. GitChat · 前端 | JavaScript 进阶之 Vue.js + Node.js 入门实战开发
  13. 数据安全与分类分级、敏感信息定义与分级分类标准
  14. C语言 汉字名字排列组合
  15. 内存中的存储空间(栈空间、堆空间、数据段、代码段)
  16. html5 css3 入门教程
  17. 跟老男孩学 Linux 运维:Web 集群实战
  18. python-pcl简易文档(不包含自建函数与pcl_grabber包)
  19. c实用技巧:纯c对于excel数据表的处理
  20. python缺点特性_day1---python的基础特性

热门文章

  1. 2016ATF阿里巴巴技术论坛
  2. 02驱动力在哪里 - 献给迷茫的测试人员
  3. hbase各个角色的分工
  4. 普通瀑布流(错落有致的排列,水平不对齐,左右对齐,下一排的图片的第一张位于上一排高度最小的照片的下面)
  5. 亚马逊跨境电商是什么,ERP软件到底有用吗
  6. Xcode历史版本下载
  7. JS如何准确判断NaN(isNaN函数不可靠问题)
  8. Flowable API
  9. flowable创建processEngine的流程
  10. 树莓派zero+mysql_树莓派zero初步调试