【发布时间】:2021-06-26 08:49:24
【问题描述】:
我有一个 java 项目,其中 PreparedStatements 没有在任何 SQL 查询中使用。现在我想为所有这些查询实现 PreparedStatements。而不是通过放置“?”来修改每个查询, 我想写一个函数,它接受 SQL 查询字符串来解析它并返回各种 SQL 子句的值的映射。
public class SQLParser {
public static void main(String args[]) {
String sqlString = "select * from table t where columnA = 'hello' and columnB = 'hai'";
Map<Integer,String> values = new HashMap<>();
values = parseQuery(sqlString);
System.out.println(values); // prints { {1,'hello'} , {2,'hai'} }
}
private static Map<Integer,String> parseQuery(String sqlString) {
Map<Integer,String> values = new HashMap<>();
//
// ???? I want this function
//
return values;
}
}
几个例子是
sqlString : select * from table t where columnA = 'hello' AND columnB = 'hai'
输出:{ {1,'hello'} , {2,'hai'} }
sqlString : select * from table t where columnA IN ('hello' ,'hai')
输出:{ {1,'hello'} , {2,'hai'} }
sqlString : select * from table t where columnA > 17 AND columnB BETWEEN 10 AND 20;
输出:{ {1,'17'} , {2, '10' } , {3, '20'} }
基本上它应该支持所有可能的子句及其组合。
【问题讨论】:
-
如果你的地图的键是递增的数字,一个列表还不够吗?
-
无论如何,您基本上是在问如何为 SQL 编写解析器(顺便说一句,哪种 SQL 方言?),如果您问我,这似乎是一个不小的壮举。我不确定它是否适合 StackOverflow 的答案。
-
无论如何,无论是使用魔法语句解析器/准备器还是直接使用
PreparedStatement,您都必须更改每个查询的代码。你真的可以开发那个神奇的解析器/准备器,然后修改每个查询以使用它,比将每个查询重写为PreparedStatement所需的时间更短吗?我们在这里讨论了多少个查询? -
我想你在这里错过了一些东西。使用 PreparedStatement 的要点是避免 SQL 注入。但是,如果您首先根据参数将 SQL 创建为字符串,则此时可以进行注入,并且您的解析器将愉快地解析恶意 SQL 语句。
标签: java sql sql-parser