找到sql里面参数字段占位符的位置,方便对字段进行加密存储

CCJSqlParserUtil工具是强大,难用也是真的,得分析sql的各种各样的表达式。从中递归找出业务需要的。

public class SqlExpressionAnalyzer {public static void main(String[] args) {String sql = "select id,user_name from sys_user t1,sys_office t2 where t1.id=t2.id and mobile =? and user_name like '%abc%' and user_name like ? and user_name like ?  and position=? and bbb in ('1','2') and ccc in (?,?) and sex='1' and (photo='abc' or headImg='abc' or user_name like '%abc%')  and nation='2'" +" and id in (select id from relation_user where acc=?) and user_name in (select user_name from table_3 where user_name in (?,?,?,?,?) and user_name in ('1','3','4')) " +"and mobile =(case when is_using=1 then '1' when is_using=0 then '2' else '3' end)";String updateSql = "update sys_user set mobile=?,user_name='张三' where mobile='1' and id='1'";String insertSql = "insert into sys_user (id,mobile,user_name) values (?,?,?)";String delSql = "delete from sys_user where mobile=? and user_name=? and mobile in (?,?,?,?,?) and user_name in ('李四','张三')";AnalyzerResult analyzerResult = parse(delSql);System.out.println(analyzerResult);}public static AnalyzerResult parse(BoundSql boundSql) {return null != boundSql ? parse(boundSql.getSql()) : AnalyzerResult.empty();}public static AnalyzerResult parse(String sql) {Statement statement;try {statement = CCJSqlParserUtil.parse(sql);} catch (JSQLParserException e) {throw new LocalException(e.getMessage());}if (statement instanceof Select) {return analyzeSelect((Select) statement);} else if (statement instanceof Update) {return analyzeUpdate((Update) statement);} else if (statement instanceof Insert) {return analyzerInsert((Insert) statement);} else if (statement instanceof Delete) {return analyzerDelete((Delete) statement);}return AnalyzerResult.empty();}private static AnalyzerResult analyzerInsert(Insert insert) {AnalyzerResult analyzerResult = new AnalyzerResult(insert.getTable());List<Column> columns = insert.getColumns();List<Expression> setExpressionList = insert.getSetExpressionList();if (null != setExpressionList && setExpressionList.size() == columns.size()) {analyzerResult.putResults(columns, setExpressionList);} else {ItemsList itemsList = insert.getItemsList();if (itemsList instanceof ExpressionList) {ExpressionList expressionList = (ExpressionList) itemsList;List<Expression> expressions = expressionList.getExpressions();analyzerResult.putResults(columns, expressions);} else if (itemsList instanceof MultiExpressionList) {MultiExpressionList multiExpressionList = (MultiExpressionList) itemsList;List<ExpressionList> exprList = multiExpressionList.getExprList();for (ExpressionList expressionList : exprList) {List<Expression> expressions = expressionList.getExpressions();analyzerResult.putResults(columns, expressions);}}}return analyzerResult;}private static AnalyzerResult analyzerDelete(Delete delete) {AnalyzerResult result = new AnalyzerResult(delete.getTable());Expression where = delete.getWhere();analyzeWhere(where, result);if (result.isExitReplaceStr()) {result.setReplaceSql(delete.toString());}return result;}private static AnalyzerResult analyzeUpdate(Update update) {List<Table> tables = update.getTables();if (tables.isEmpty()) {return AnalyzerResult.empty();}AnalyzerResult result = new AnalyzerResult(tables.get(FIRST));List<Column> columns = update.getColumns();List<Expression> expressions = update.getExpressions();result.putResults(columns, expressions);Expression where = update.getWhere();analyzeWhere(where, result);if (result.isExitReplaceStr()) {result.setReplaceSql(update.toString());}return result;}private static AnalyzerResult analyzeSelect(Select select) {PlainSelect plainSelect = (PlainSelect) select.getSelectBody();// 分析表达式AnalyzerResult result = new AnalyzerResult((Table) plainSelect.getFromItem());analyzeWhere(plainSelect.getWhere(), result);// 替换sqlif (result.isExitReplaceStr()) {result.setReplaceSql(plainSelect.toString());}return result;}private static void analyzeWhere(Expression expression, AnalyzerResult result) {if (null == expression) {return;}// 正常xxx xxx xxxif (expression instanceof BinaryExpression) {BinaryExpression binaryExpression = (BinaryExpression) expression;Expression leftExpression = binaryExpression.getLeftExpression();Expression rightExpression = binaryExpression.getRightExpression();boolean isColumn = leftExpression instanceof Column;boolean isString = rightExpression instanceof StringValue;boolean isJdbc = rightExpression instanceof JdbcParameter;boolean isValue = isString || isJdbc;if (isColumn && isValue) {Column column = (Column) leftExpression;boolean isLike = expression instanceof LikeExpression;result.putResult(column, rightExpression, isLike);} else {analyzeWhere(leftExpression, result);analyzeWhere(rightExpression, result);}// in查询} else if (expression instanceof InExpression) {InExpression binaryExpression = (InExpression) expression;Expression leftExpression = binaryExpression.getLeftExpression();ItemsList rightItemsList = binaryExpression.getRightItemsList();ItemsList leftItemsList = binaryExpression.getLeftItemsList();if (leftExpression instanceof Column) {Column column = (Column) leftExpression;boolean isInValue = false;ExpressionList expressionList = null;if (rightItemsList instanceof ExpressionList) {isInValue = true;expressionList = (ExpressionList) rightItemsList;} else if (leftItemsList instanceof ExpressionList) {isInValue = true;expressionList = (ExpressionList) leftItemsList;}if (isInValue) {result.putResults(column, expressionList.getExpressions());} else {if (rightItemsList instanceof Expression) {analyzeWhere((Expression) rightItemsList, result);}if (leftItemsList instanceof Expression) {analyzeWhere((Expression) leftItemsList, result);}}}// 子语句} else if (expression instanceof Parenthesis) {Parenthesis parenthesis = (Parenthesis) expression;Expression parenthesisExpression = parenthesis.getExpression();analyzeWhere(parenthesisExpression, result);// 子查询} else if (expression instanceof SubSelect) {SubSelect subSelect = (SubSelect) expression;PlainSelect selectBody = (PlainSelect) subSelect.getSelectBody();Expression where = selectBody.getWhere();analyzeWhere(where, result);// case when里面的when条件} else if (expression instanceof CaseExpression) {CaseExpression caseExpression = (CaseExpression) expression;List<WhenClause> whenClauses = caseExpression.getWhenClauses();if (ZYListUtils.isNotEmptyList(whenClauses)) {for (WhenClause whenClause : whenClauses) {Expression whenExpression = whenClause.getWhenExpression();analyzeWhere(whenExpression, result);}}} else {log.warn("not handle expression" + expression.getClass());}}}
@Data
public class AnalyzerResult {private boolean exitReplaceStr = false;private String replaceSql;private String tableName;private List<ColumnInfo> jdbcColumnInfos = new ArrayList<>();private List<ColumnInfo> signJdbcColumnInfos = new ArrayList<>();public AnalyzerResult(Table table) {this.tableName = table.getName();}public AnalyzerResult() {}public Set<Integer> getCryptIndexs() {Set<Integer> cryptIndexs = new HashSet<>();for (ColumnInfo jdbcColumnInfo : jdbcColumnInfos) {cryptIndexs.add(jdbcColumnInfo.getJdbcIndex());}return cryptIndexs;}public void putResults(Column column, List<Expression> expressions) {if (null != expressions) {for (Expression expression : expressions) {putResult(column, expression, false);}}}public void putResults(List<Column> columns, List<Expression> expressions) {if (ZYListUtils.isSingletonList(columns) || ZYListUtils.isEmptyList(expressions)) {return;}for (int i = 0; i < columns.size(); i++) {Column column = columns.get(i);Expression expression = expressions.get(i);this.putResult(column, expression);}}public void putResult(Column column, Expression expression) {putResult(column, expression, false);}public void putResult(Column column, Expression expression, boolean isLike) {if (SecurityColumnProviders.matchSecret(this.tableName, column)) {if (expression instanceof JdbcParameter) {JdbcParameter jdbcParameter = (JdbcParameter) expression;this.jdbcColumnInfos.add(new ColumnInfo(column, jdbcParameter));} else if (expression instanceof StringValue) {this.setExitReplace();toReplaceString((StringValue) expression, isLike);}}if (SecurityColumnProviders.matchSign(this.tableName, column)) {if (expression instanceof JdbcParameter) {JdbcParameter jdbcParameter = (JdbcParameter) expression;this.signJdbcColumnInfos.add(new ColumnInfo(column, jdbcParameter));}}}private void toReplaceString(StringValue rightExpression, boolean isLike) {String value = rightExpression.getValue();if (ZYStrUtils.isNull(value)) {return;}SecretProviders secretProviders = ZYSpringUtils.getBean(SecretProviders.class);if (null == secretProviders) {throw new LocalException("secretProviders is null");}if (isLike && value.startsWith("%") && value.endsWith("%")) {String valueItem = value.substring(1, value.length() - 2);String encryptValue = secretProviders.encrypt(valueItem);rightExpression.setValue("%" + encryptValue + "%");} else {rightExpression.setValue(secretProviders.encrypt(value));}}private void setExitReplace() {this.exitReplaceStr = true;}public static AnalyzerResult empty() {return new AnalyzerResult();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/50994.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript语法基础之DOM基础

目录 1. DOM 基础 1.1. DOM 是什么&#xff1f; 1.1.1. DOM 对象 1.1.2. DOM 结构 1.2. 节点类型 1.3. 获取元素 1.3.1. getElementById() 1.3.2. getElementsByTagName() 1.3.3. getElementsByClassName() 1.3.4. getElementsByName() 1.4.如何去操作对象 修改属性…

Jenkins 定时触发策略

每天晚上 11 点执行一次&#xff0c;可以按照以下步骤进行。 复制代码 import jenkins import datetime import base64USERNAME bUFNXssaaX0NU\n PASSWORD bUFNXXssdds0Ndclass JenkinsMonitor:def __init__(self, jobs_to_monitor):self.jenkins_url "http://pe-dddd…

fastJSON工具类

1 总结 1&#xff1a; JSONObject&#xff1a; 理解为 Map 2&#xff1a;JSONArray &#xff1a; 理解为List<Map> 3&#xff1a;JSON.toJSONString()&#xff1b;会将时间转为时间戳 4&#xff1a;toJSONStringWithDateFormat 同一个字符串中 时间格式是统一格式 2 转成…

IP SSL证书的未来趋势:适应不断变化的安全挑战

随着网络攻击手段的不断进化和用户对隐私保护意识的增强&#xff0c;IP SSL证书作为保障网络安全的关键组件之一&#xff0c;也在不断地发展和完善。本文将探讨IP SSL证书的未来趋势&#xff0c;以及如何适应这些不断变化的安全挑战。 当前状况与挑战 网络安全意识提升&#…

ARM 裸机与 Linux 驱动对比及 Linux 内核入门

目录 ARM裸机代码和驱动的区别 Linux系统组成 内核五大功能 设备驱动分类 内核类型 驱动模块 驱动模块示例 Makefile配置 命令 编码辅助工具 内核中的打印函数 printk 函数 修改打印级别 ​编辑 打印级别含义 驱动多文件编译 示例 模块传递参数 命令行传递参数…

AND 运算符的优先级高于 OR

在 SQL 中&#xff0c;AND 运算符的优先级高于 OR。这意味着您的查询可能会不按预期执行。为了确保逻辑的正确性&#xff0c;您可能需要使用括号来明确指定运算符的优先级。 正确的&#xff1a;and后用括号把or括起来 SELECT * FROM student WHERE data_status 0 AND (name L…

python-docx 实现 Word 办公自动化

前言&#xff1a;当我们需要批量生成一些合同文件或者简历等。如果手工处理对于我们来说不仅工作量巨大&#xff0c;而且难免会出现一些问题。这个时候运用python处理word实现自动生成文件可极大的提高工作效率。 python-docx是python的第三方插件&#xff0c;用来处理word文件…

图像直方图比较

对于直方图的比较&#xff0c;我们可以使用 OpenCV 提供的函数 compareHist() 进行比较&#xff0c;从而得到一个数值&#xff0c;表示两个直方图的匹配程度&#xff08;相似性&#xff09;。 原理 对于两个直方图&#xff08; H 1 H_{1} H1​ 和 H 2 H_{2} H2​&#xff09…

【大数据】基础认知入门

目录 前言阅读对象阅读导航前置知识笔记正文一、什么是大数据1.1 定义1.2 特点1.3 数据结构1.4 补充总结 二、大数据能用来干什么2.1 应用方向2.2 应用场景&#xff08;简述&#xff09;2.3 总结 三、大数据一般性过程四、给自己的作业 感谢说在后面 前言 唉&#xff0c;最近有…

Kubectl命令、初识pod、namespace

文章目录 一、Kubectl简介基础命令1.基本信息命令2.创建和更新资源命令3.删除资源命令4. 查看日志和调试命令5. 端口转发和复制文件命令6. 部署管理命令7. 伸缩命令8. 配置和上下文管理命令9.常用命令 二、Pod简介核心概念pod常见状态调度和初始化阶段容器创建和运行阶段异常状…

Qt网络通信——TCP和UDP

一、TCP通信 TCP通信必须先建立 TCP 连接&#xff0c;通信端分为客户端和服务器端。 Qt 为服务器端提供了 QTcpServer 类用于实现端口监听&#xff0c;QTcpSocket 类则用于服务器和客户端之间建立连接。大致流程如下图所示&#xff1a; 1. 服务器端建立 1.1 监听——listen() …

PPP简介

介绍PPP特性的定义和目的。 定义 PPP&#xff08;Point-to-Point Protocol&#xff09;协议是一种点到点链路层协议&#xff0c;主要用于在全双工的同异步链路上进行点到点的数据传输。 目的 PPP协议是在串行线IP协议SLIP&#xff08;Serial Line Internet Protocol&#x…

【Android高级UI】将View或Layout裁剪为任意形状

需求 将View裁剪为指定形状 将Layout裁剪为指定形状&#xff0c;并且Children不能超过裁剪范围 应用 圆角图片异形图片圆角Layout 方案 通过ViewOutlineProvider裁剪控件范围 实现 fun View.getMeasureSize(): Size {val widthSpec View.MeasureSpec.makeMeasureSpec(…

代码随想录:动态规划6-10

62、不同路径 题目 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径…

Hadoop入门基础(三):Hadoop启动踩坑记录

一、机器ssh连接方式非默认22端口 报错&#xff1a; sbin/start-dfs.sh Starting namenodes on [doop253] doop253: ssh: connect to host doop253 port 22: Connection refused 解决方法&#xff1a; sudo vim /etc/ssh/ssh_config 添加如下内容&#xff08;注意替换自己服…

[Qt] 避免CMake编译的Qt程序单独运行时出现控制台窗口的解决办法

只需要在add_executable中加上WIN32即可 避免CMake编译的Qt程序单独运行时出现控制台窗口的解决办法

史上最全的软件工厂考试简答题教程

软件工程考试简答题 1. 有人认为软件开发时&#xff0c;一个错误发现得越晚&#xff0c;为改正它所付出的代价越大。提出你的观点并解释原因&#xff1f; &#xff08;1&#xff09;在软件开发的不同阶段进行修改付出的代价是很不相同的&#xff0c;在早期引入变动&#xff0c…

【Harmony OS 4.0】交互事件(手势事件)

1. 绑定手势方法 1.1 gesture&#xff08;常规手势绑定方法&#xff09; 1.2 priorityGesture&#xff08;带优先级的手势绑定方法&#xff09; 1.3 parallelGesture&#xff08;并行手势绑定方法&#xff09; 可以在父子组件上绑定。可以同时响应的相同手势。当父组件绑定了…

如何清理win备用内存?备用内存过大怎么办?

下载这个软件RamMap 运行以后 选择Empty-Empty Standby List就行了 参考&#xff1a;https://www.zhihu.com/question/263768043 另外&#xff0c;禁用服务中的SystemMain&#xff0c;应该会停止占用备用内存&#xff0c;但是需要重启。 所以没办法只好创建一个任务计划&…

openai whisper使用

whisper使用 介绍 Whisper是一种通用的语音识别模型。它是在大量不同音频数据集上训练的&#xff0c;也是一个多任务模型&#xff0c;可以执行多语言语音识别、语音翻译和语言识别。 GitHub&#xff1a;https://github.com/openai/whisper 论文链接&#xff1a;https://arx…