当前位置: 首页 > news >正文

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);}}}
http://www.jsqmd.com/news/200812/

相关文章:

  • 死锁的定义是指多个进程(或线程)在执行过程中,由于竞争资源或彼此通信而造成的一种阻塞现象
  • Meta数十亿美元收购Butterfly Effect:中国AI团队如何打造自主智能体并成功出海
  • Java并发利器:CyclicBarrier深度解析
  • Mybatis-plus自动填充字段
  • 深入解析AI Agent五件套:从感知到学习的完整指南【必收藏】
  • 【必学收藏】大模型架构深度解析:一文读懂自注意力机制原理与代码实现
  • 【QWen1.5】使用AutoDL多卡对QWen1.5-7B模型进行lora微调
  • 原创大规模无人机检测数据集:11998张高质量图像,支持YOLOv8、COCO、TensorFlow多格式训练,涵盖飞机、无人机、直升机三大目标类别
  • 为什么大模型如此强大我们还要微调?程序员必收藏的微调详解
  • 网页自动翻页工具(执行PageDown)
  • 在 IntelliJ IDEA 中使用 JUnit 进行单元测试 - 详解
  • 【值得收藏】MCP协议入门到实战:大模型与外部系统交互的通用桥梁,附代码与学习资源
  • 收藏必备!从零构建AI Agent:知识库、工作流与Prompt工程实战指南
  • 从入门到精通:企业级RAG系统实战指南,收藏级RAG开发全流程解析
  • CSS极坐标的实例代码
  • 数学总结
  • 2025 年度总结:在坚持与突破中前行
  • 你的网站SSL证书又要过期了?这个工具能让你永久告别焦虑
  • 【必收藏】法律大模型实战:从文档到知识图谱的RAG系统构建全攻略
  • 2026爆火6款免费AI论文生成器:1小时初稿全学科覆盖!
  • RAG全栈学习笔记-Graph RAG
  • 【珍藏】从零掌握大模型检索增强技术:RAG到GraphRAG的完整指南
  • Ftp服务部署
  • 实用指南:Node.js:从浏览器到服务器的JS革命
  • 【必学收藏】MoE架构深度解析:大模型高效训练的核心技术与实战应用
  • 本地知识库:你的数据安全守护者
  • 【必学收藏】从入门到精通:Prompt工程的演变、价值与实战技巧
  • 智能学习资源管理平台 - Beta冲刺总结
  • 牛批了,windows系统神器,一键搞定
  • Linux 中 awk 利用外部文件传入数字变量,利用循坏提取特定列