Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SQL查询中找到条件并用Java替换它1=1_Java - Fatal编程技术网

如何在SQL查询中找到条件并用Java替换它1=1

如何在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做到这

我有一个sql查询,它在where子句、having子句或in join中有一个条件。我需要找到包含如下括号的值的条件:{some name},并在某些情况下用java将该条件替换为1=1

例如

我想用AND |拆分where条件,或者检查它是否包含{var2},然后用1=1替换,但这不起作用。在上面描述的示例中,在拆分之后,它将是类似于{var2}的c.name,因此也将被替换

是否有人遇到过这种情况以及如何解决。 有没有开源的libraray可以找到并替换它,或者我怎样才能用regex做到这一点

首先,我假设您无法动态构建sql。为此,您可以采用简单的方式,使用字符串concats构建sql,例如

"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");