如何在SQL查询中找到条件并用Java替换它1=1
我有一个sql查询,它在where子句、having子句或in join中有一个条件。我需要找到包含如下括号的值的条件:{some name},并在某些情况下用java将该条件替换为1=1 例如 我想用AND |拆分where条件,或者检查它是否包含{var2},然后用1=1替换,但这不起作用。在上面描述的示例中,在拆分之后,它将是类似于{var2}的c.name,因此也将被替换 是否有人遇到过这种情况以及如何解决。 有没有开源的libraray可以找到并替换它,或者我怎样才能用regex做到这一点 首先,我假设您无法动态构建sql。为此,您可以采用简单的方式,使用字符串concats构建sql,例如如何在SQL查询中找到条件并用Java替换它1=1,java,Java,我有一个sql查询,它在where子句、having子句或in join中有一个条件。我需要找到包含如下括号的值的条件:{some name},并在某些情况下用java将该条件替换为1=1 例如 我想用AND |拆分where条件,或者检查它是否包含{var2},然后用1=1替换,但这不起作用。在上面描述的示例中,在拆分之后,它将是类似于{var2}的c.name,因此也将被替换 是否有人遇到过这种情况以及如何解决。 有没有开源的libraray可以找到并替换它,或者我怎样才能用regex做到这
"select ... where c.id > " + myvalue + " ... "
如果您能保证表达式只查找sql的特定部分,而不查找更多部分,那么对sql使用正则表达式是可行的。这听起来有点微不足道,但对于特定的SQL来说很难实现,例如:
select '{var2}' from mytable
{var2}是否应在此处替换?我认为不是,因为它是字符串文字的一部分,而不是where语句的一部分
因此,您需要对sql解析器提供的sql进行更结构化的查看
使用例如JSqlParser,您将能够识别where语句的部分,并以可控的方式替换SQL的部分
但是为了进行这种解析,您必须用符合SQL的东西来替换{val},例如u val_u
因此,您的替换可以通过以下代码实现。它假设替换只在正确的表达式中完成,但您可以轻松地更改它
String sqlTxt = "Select * from customer c inner join address a on c.id = a.customer_id where c.id > {var1} AND (c.name LIKE {var2} OR a.city = {var3})";
//replace macro constructs
String sql = sqlTxt.replace("{", "__").replace("}", "__");
//build replacement data
Map<String, String> data = new HashMap<>();
data.put("__var1__", "2");
data.put("__var2__", "*ALL");
data.put("__var3__", "'aa'");
//parse sql
Select select = (Select) CCJSqlParserUtil.parse(sql);
StringBuilder b = new StringBuilder(sql);
//rewrite sql to fit your needs
((PlainSelect) select.getSelectBody()).getWhere().accept(new ExpressionVisitorAdapter() {
int delta = 0; //to correct the position due to former replacements
@Override
protected void visitBinaryExpression(BinaryExpression expr) {
if (expr instanceof ASTNodeAccess) {
if (expr.getRightExpression() instanceof Column) {
Column c = ((Column) expr.getRightExpression());
if (data.containsKey(c.getColumnName())) {
if ("__var2__".equals(c.getColumnName())) {
delta = replaceASTNodeWith(b, delta, (ASTNodeAccess) expr, "1=1");
} else {
delta = replaceASTNodeWith(b, delta, (ASTNodeAccess) expr,
expr.getLeftExpression() + expr.getStringExpression() + data.get(c.getColumnName()));
}
}
}
}
super.visitBinaryExpression(expr);
}
});
System.out.println("parsed sql = " + select.toString());
System.out.println("changed sql = " + b.toString());
这不会回答你的问题,但更多的是关于我如何使用1=1方法的建议 我想你可能想写这样的东西
String query = "select * from customer c inner join address a on c.id = a.customer_id where 1=1"
if(var1 != null)
query += "and c.id > " + var1
if(var2 != null)
query += "and c.name LIKE " + var2
if(var3 != null)
query += "and a.city = " + var3
例如,你想要有这样的逻辑,它看起来会有点棘手
//you should realize that 1=1 here to make sure that we add "AND " command
String query = "select * from customer c inner join address a on c.id = a.customer_id where 1=1"
if(var1 != null)
query += "and c.id > " + var1
if(var2 != null && var3 != null) { //because if var2 or var3 is all, then return all.
query += "and ( c.name LIKE " + var2;
query += "or a.city = " + var3 + ")";
}
希望此帮助使用以下内容:-
如果是{singleWord}之间的单字变量
queryString = queryString.replaceAll("\\{[A-Za-z0-9]+\\}", "1=1");
如果是{multi-word}之间的多字变量
queryString = queryString.replaceAll("\\{[A-Za-z0-9\\s]+\\}", "1=1");
有关更多详细信息,请参阅:-是否要编写一些复杂的查询,如果不需要,请将其替换为1=1?我不推荐这种方法。最好是动态生成where语句。
queryString = queryString.replaceAll("\\{[A-Za-z0-9]+\\}", "1=1");
queryString = queryString.replaceAll("\\{[A-Za-z0-9\\s]+\\}", "1=1");