news 2026/6/10 22:28:45

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/6/10 19:46:50

Ftp服务部署

目录 一、安装 vsftpd 二、核心配置&#xff08;匿名 / 本地用户模式&#xff09; 1.匿名访问模式&#xff08;默认开启&#xff0c;建议关闭&#xff09; 2.创建 FTP 本地用户 一、安装 vsftpd # Centos 安装 vsftpd sudo yum install vsftpd -y# Ubuntu 安装 vsftpd sud…

作者头像 李华
网站建设 2026/6/10 16:03:29

智能学习资源管理平台 - Beta冲刺总结

冲刺概述冲刺时间- 开始时间&#xff1a;2024-12-01- 结束时间&#xff1a;2024-12-15- 冲刺周期&#xff1a;15天冲刺目标本次Beta冲刺的主要目标是&#xff1a;1. 优化系统性能&#xff0c;提升用户体验2. 完善核心功能&#xff0c;增强系统稳定性3. 增加新功能&#xff0c;提…

作者头像 李华
网站建设 2026/6/10 15:24:57

语义理解十年演进(2015–2025)

语义理解十年演进&#xff08;2015–2025&#xff09; 一句话总论&#xff1a; 2015年语义理解还是“词向量规则匹配浅层语义角色标注”的符号主义时代&#xff0c;2025年已进化成“万亿级多模态VLA大模型端到端意图直出量子鲁棒自进化全域社交语义闭环”的通用智能时代&#x…

作者头像 李华
网站建设 2026/6/10 16:03:33

文本生成十年演进(2015–2025)

文本生成十年演进&#xff08;2015–2025&#xff09; 一句话总论&#xff1a; 2015年文本生成还是“Seq2SeqRNNBeam Search”的短句机械时代&#xff0c;2025年已进化成“万亿级多模态VLA大模型意图级自一致长文本量子加速自进化全域社交/创意/专业写作”的普惠神器&#xff0…

作者头像 李华
网站建设 2026/6/10 15:59:01

netmsg.dll文件损坏丢失找不到 打不开软件 下载方法分享

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

作者头像 李华