news 2026/4/2 12:33:39

JSQLParser解析SQL神器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JSQLParser解析SQL神器

JsqlParserUtils
sql解析通用工具

/** * SQL解析通用工具 **/@Slf4jpublicclassJsqlParserUtils{publicstaticStringassembleDeriveQuerySql(Stringsql,Expressionexpression){if(expression==null){returnsql;}Statementparse=null;try{parse=CCJSqlParserUtil.parse(sql);if(!(parseinstanceofSelect)){returnsql;}Selectselect=(Select)parse;if(selectinstanceofPlainSelect){PlainSelectplainSelect=select.getPlainSelect();Expressionwhere=plainSelect.getWhere();if(where!=null){plainSelect.setWhere(newAndExpression(where,expression));}else{plainSelect.setWhere(expression);}}returnparse.toString();}catch(JSQLParserExceptione){log.error("解析sql失败,msg={}",e.getMessage(),e);thrownewBusinessException(ErrorEnum.DAL_SQL_ANALYSIS_ERROR);}}/** * 获取sql语句的最外层select对象 * * @param sql 解析的sql语句 */publicstaticList<SelectItemDto>getOutermostSelectItems(Stringsql,Statementparse){if(StrUtil.isBlank(sql)&&parse==null){thrownewBusinessException(ErrorEnum.DAL_SQL_IS_NULL);}try{if(parse==null){parse=CCJSqlParserUtil.parse(sql);}if(!(parseinstanceofSelect)){thrownewBusinessException(ErrorEnum.DAL_IS_NOT_SELECT_SQL);}SelectselectBody=((Select)parse);if(selectBodyinstanceofPlainSelect){PlainSelectplainSelect=selectBody.getPlainSelect();List<SelectItem<?>>selectItems=plainSelect.getSelectItems();if(CollUtil.isEmpty(selectItems)){returnnewArrayList<>();}FromItemfromItem=plainSelect.getFromItem();StringoriginalTableName=null;StringtableAlias=null;StringtableName=null;if(fromItem!=null){originalTableName=fromItem.toString();Aliasalias=fromItem.getAlias();if(alias!=null){tableAlias=alias.getName();}tableName=StrUtil.isBlank(tableAlias)?originalTableName:tableAlias;}List<SelectItemDto>selectItemDtos=newArrayList<>();List<MdpSqlFieldCommentData>feildCommentDataList=newArrayList<>();for(SelectItem<?>selectItem:selectItems){SqlCommentUtil.extractColumnComments(sql,selectItem,feildCommentDataList);SelectItemDtoselectItemDto=newSelectItemDto();selectItemDto.setOriginalTableName(originalTableName);selectItemDto.setTableAlias(tableAlias);selectItemDto.setTableName(tableName);Aliasalias=selectItem.getAlias();selectItemDto.setColumnName(selectItem.getExpression().toString());if(alias!=null){selectItemDto.setAliasName(alias.getName());}selectItemDto.setSelectItemName(StrUtil.isBlank(selectItemDto.getAliasName())?selectItemDto.getColumnName():selectItemDto.getAliasName());selectItemDtos.add(selectItemDto);}if(CollUtil.isNotEmpty(feildCommentDataList)){MdpSqlFieldCommentDataServicemdpSqlFieldCommentDataService=SpringUtil.getBean(MdpSqlFieldCommentDataService.class);mdpSqlFieldCommentDataService.saveOrUpdateEntityBatch(feildCommentDataList);}returnselectItemDtos;}}catch(Exceptione){thrownewBusinessException(ErrorEnum.DAL_SQL_ANALYSIS_SELECT_ITEM_ERROR);}returnnewArrayList<>();}/** * 获取sql语句的最外层select字段 * * @param sql 解析的sql语句 */publicstaticList<String>getOutermostSelectItemNames(Stringsql,Statementparse){returngetOutermostSelectItems(sql,parse).stream().map(SelectItemDto::getSelectItemName).collect(Collectors.toList());}publicstaticbooleanhasGroupBy(Stringsql){try{Statementparse=CCJSqlParserUtil.parse(sql);if(parseinstanceofSelect){Selectselect=(Select)parse;PlainSelectplainSelect=select.getPlainSelect();GroupByElementgroupBy=plainSelect.getGroupBy();returngroupBy!=null;}else{returnfalse;}}catch(JSQLParserExceptione){log.error("addSelectItem 解析sql失败,msg={}",e.getMessage(),e);thrownewBusinessException(ErrorEnum.DAL_SQL_ANALYSIS_ERROR);}}/** * 在sql中新增select 字段 * <p> * 如果select字段已经存在,则不重复添加 * * @param sql 需要处理的sql * @param selectItemColumns 需要新增的select字段集合 * @return 处理完成之后的sql */publicstaticStringaddSelectItem(Stringsql,List<String>selectItemColumns){if(CollectionUtils.isEmpty(selectItemColumns)){returnsql;}Statementparse=null;PlainSelectplainSelect=null;try{parse=CCJSqlParserUtil.parse(sql);}catch(JSQLParserExceptione){log.error("addSelectItem 解析sql失败,msg={}",e.getMessage(),e);thrownewBusinessException(ErrorEnum.DAL_SQL_ANALYSIS_ERROR);}if(parseinstanceofSelect){Selectselect=(Select)parse;plainSelect=select.getPlainSelect();List<SelectItem<?>>selectItems=select.getPlainSelect().getSelectItems();List<String>originalSelectItemColumns=newArrayList<>();for(SelectItem<?>selectItem:selectItems){Aliasalias=selectItem.getAlias();if(alias!=null){originalSelectItemColumns.add(alias.getName());}else{originalSelectItemColumns.add(selectItem.getExpression().toString());}}//获取两个集合的单差集(selectItemColumns有,originalSelectItemColumns没有的元素)List<String>subtractList=CollUtil.subtractToList(selectItemColumns,originalSelectItemColumns);if(CollUtil.isNotEmpty(subtractList)){//新增select字段for(StringaddSelectItem:subtractList){SelectItem<Column>selectExpressionItem=newSelectItem<>();Columncolumn=newColumn();column.setColumnName(addSelectItem);selectExpressionItem.setExpression(column);selectItems.add(selectExpressionItem);}}}returnplainSelect==null?sql:plainSelect.toString();}/** * 在sql中删除select 字段 * <p> * 删除select 字段 * * @param sql 需要处理的sql * @param removeSelecretItemColumns 需要删除的select字段集合 * @return 处理完成之后的sql */publicstaticStringremoveSelectItem(Stringsql,List<String>removeSelecretItemColumns){if(CollectionUtils.isEmpty(removeSelecretItemColumns)){returnsql;}Statementparse=null;PlainSelectplainSelect=null;try{parse=CCJSqlParserUtil.parse(sql);}catch(JSQLParserExceptione){log.error("removeSelectItem 解析sql失败,msg={}",e.getMessage(),e);thrownewBusinessException(ErrorEnum.DAL_SQL_ANALYSIS_ERROR);}if(parseinstanceofSelect){Selectselect=(Select)parse;plainSelect=select.getPlainSelect();List<SelectItem<?>>selectItems=plainSelect.getSelectItems();Iterator<SelectItem<?>>iterator=selectItems.iterator();while(iterator.hasNext()){SelectItem<?>selectItem=iterator.next();StringselectItemStr=selectItem.toString();Aliasalias=selectItem.getAlias();if(alias!=null){selectItemStr=alias.getName();}if(removeSelecretItemColumns.contains(selectItemStr)){iterator.remove();}}}returnplainSelect==null?sql:plainSelect.toString();}/** * 在sql中新增group by字段 * <p> * 如果group by字段已经存在,则不重复添加 * * @param sql 需要处理的sql * @param groupByColumns 需要新增的group by字段集合 * @return 处理完成之后的sql */publicstaticStringaddGroupBy(Stringsql,List<String>groupByColumns){if(CollectionUtils.isEmpty(groupByColumns)){returnsql;}Statementparse=null;PlainSelectplainSelect=null;try{parse=CCJSqlParserUtil.parse(sql);}catch(JSQLParserExceptione){log.error("addGroupBy 解析sql失败,msg={}",e.getMessage(),e);thrownewBusinessException(ErrorEnum.DAL_SQL_ANALYSIS_ERROR);}if(parseinstanceofSelect){Selectselect=(Select)parse;plainSelect=select.getPlainSelect();GroupByElementgroupBy=plainSelect.getGroupBy();if(groupBy==null){//如果没有groupBy元素,则创建一个groupBy=newGroupByElement();plainSelect.setGroupByElement(groupBy);}ExpressionListgroupByExpressionList=groupBy.getGroupByExpressionList();List<Expression>expressions=groupByExpressionList.getExpressions();if(CollUtil.isNotEmpty(expressions)){for(Expressionexpression:expressions){//只考虑列的情况if(expressioninstanceofColumn){Columncolumn=(Column)expression;StringcolumnName=column.getColumnName();//如果新增的列名已经有了则不重复添加groupByColumns.remove(columnName);}}}groupByExpressionList.addExpressions(groupByColumns.stream().distinct().map(Column::new).toArray(Column[]::new));}returnplainSelect==null?sql:plainSelect.toString();}/** * 在sql中删除group by字段 * <p> * * @param sql 需要处理的sql * @param removeGroupreByColumns 需要删除的group by字段集合 * @return 处理完成之后的sql */publicstaticStringremoveGroupBy(Stringsql,List<String>removeGroupreByColumns){if(CollectionUtils.isEmpty(removeGroupreByColumns)){returnsql;}Statementparse=null;PlainSelectplainSelect=null;try{parse=CCJSqlParserUtil.parse(sql);}catch(JSQLParserExceptione){log.error("removeGroupBy 解析sql失败,msg={}",e.getMessage(),e);thrownewBusinessException(ErrorEnum.DAL_SQL_ANALYSIS_ERROR);}if(parseinstanceofSelect){Selectselect=(Select)parse;plainSelect=select.getPlainSelect();GroupByElementgroupBy=plainSelect.getGroupBy();if(groupBy==null){returnsql;}ExpressionListgroupByExpressionList=groupBy.getGroupByExpressionList();List<Expression>expressions=groupByExpressionList.getExpressions();if(CollUtil.isNotEmpty(expressions)){Iterator<Expression>iterator=expressions.iterator();while(iterator.hasNext()){Expressionexpression=iterator.next();StringcolumnStr=expression.toString();if(removeGroupreByColumns.contains(columnStr)){iterator.remove();}}}}returnplainSelect==null?sql:plainSelect.toString();}/** * 判断输入的SQL语句是否为SELECT语句,如果不是则报错。 * * @param sql 输入的SQL语句 */publicstaticvoidcheckSelectStatement(Stringsql){if(StrUtil.isBlank(sql)){thrownewBusinessException(ErrorEnum.DAL_IS_NOT_SELECT_SQL);}try{if(!(CCJSqlParserUtil.parse(sql)instanceofSelect)){thrownewBusinessException(ErrorEnum.DAL_IS_NOT_SELECT_SQL);}}catch(JSQLParserExceptione){thrownewBusinessException(ErrorEnum.DAL_SQL_ANALYSIS_ERROR);}}}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/15 22:37:11

救命神器2026 TOP10 AI论文工具:本科生毕业论文写作全测评

救命神器2026 TOP10 AI论文工具&#xff1a;本科生毕业论文写作全测评 2026年学术写作工具测评&#xff1a;为什么你需要这份榜单&#xff1f; 随着人工智能技术的不断进步&#xff0c;AI论文工具已经成为本科生撰写毕业论文的重要辅助手段。然而&#xff0c;面对市场上种类繁多…

作者头像 李华
网站建设 2026/4/1 4:58:03

2026爆火6款AI论文工具:一键生成初稿,写论文从未如此简单!

前言&#xff1a;2026毕业季倒计时&#xff0c;你的论文还在“难产”吗&#xff1f; 凌晨3点的图书馆、导师第8次打回的修改意见、查重率40%的红色警告、离截止日只剩72小时却连初稿框架都没搭好…… 如果你正被这些“论文噩梦”缠上&#xff0c;那这篇文章就是你的24小时急救…

作者头像 李华
网站建设 2026/3/26 12:06:30

netsh.exe文件损坏丢失找不到 打不开 下载方法分享

在使用电脑系统时经常会出现丢失找不到某些文件的情况&#xff0c;由于很多常用软件都是采用 Microsoft Visual Studio 编写的&#xff0c;所以这类软件的运行需要依赖微软Visual C运行库&#xff0c;比如像 QQ、迅雷、Adobe 软件等等&#xff0c;如果没有安装VC运行库或者安装…

作者头像 李华
网站建设 2026/3/31 16:36:56

全网最全专科生必备AI论文软件TOP8:开题报告文献综述神器测评

全网最全专科生必备AI论文软件TOP8&#xff1a;开题报告文献综述神器测评 2026年专科生必备AI论文软件测评&#xff1a;为何值得一看&#xff1f; 在当前学术写作日益智能化的背景下&#xff0c;专科生群体面临着开题报告、文献综述等环节的重重挑战。传统的写作方式不仅效率低…

作者头像 李华