【问题标题】:PreparedStatement on Java and probability to set parametersJava 上的 PreparedStatement 和概率设置参数
【发布时间】:2012-03-05 21:33:42
【问题描述】:

有一种在java中使用准备好的语句的好方法,其中有可能设置某些参数可以或不可以设置?

假设我有一个像这样的完整查询:

SELECT * FROM Table1 WHERE Field1='....' AND Field2='....' AND Field3='....'

然后在我的程序中我想做这样的事情(我知道我写的方式是不可能的)

// part of code where I have 3 variable set by some logic and the query itself
//.........

String Query = "SELECT * FROM Table1 WHERE Field1=? ";
PreparedStatement s = conn.prepareStatement();          
s.setString(1, Field1Var);

if (Field2Var != Value)
{
    Query += " AND Field2=? ";
    s.setString(2, Field2Var);
}

if (Field3Var != Value3)
{
    Query += " AND Field3=? ";
    s.setString(3, Field3Var);
}
s = conn.prepareStatement(query);   

如何在不编写许多不同查询的情况下实现它?

【问题讨论】:

  • 您可以创建一个存储过程并使用您的参数执行该过程

标签: java mysql prepared-statement


【解决方案1】:
String query = "SELECT * FROM Table1 WHERE 1=1";

if (Field1Var != Value1) {
    query += " AND Field1 = ? ";
}

if (Field2Var != Value2) {
    query += " AND Field2 = ? ";
}

if (Field3Var != Value3) {
    query += " AND Field3 = ? ";
}

PreparedStatement s = conn.prepareStatement(query); 

int i = 0;

if (Field1Var != Value1) {
    s.setString(++i, Field1Var);
}

if (Field2Var != Value2) {
    s.setString(++i, Field2Var);
}

if (Field3Var != Value3) {
    s.setString(++i, Field3Var);
}
  1. 使用附加条件 1=1。
  2. 使用计数器变量。

或者你可以像我一样写一个“NamedPreparedStatement”。 (https://gist.github.com/1978317)

【讨论】:

  • 我不喜欢你的回答,因为它没有回答我的问题,第二但同样重要的是,你不能在准备语句之前设置变量......所以 setString 方法返回一个错误,因为那里没有 ?而且你不能在没有参数的情况下调用prepareStatement方法......
  • 对不起,现在应该可以了。但我想我还是没明白你的问题。
【解决方案2】:

你不能。准备好的语句的全部意义在于它是“准备好的” - 这意味着它被解析(由驱动程序或服务器)并且您每次运行所做的只是提供参数。

您尝试编写的代码也将成为其他任何人的噩梦。如果您只是吸收它并编写查询,它会更干净。 (或使用 ORM 工具。)

【讨论】:

  • 是的,我知道,但是如果我的查询可以或不能有基于某些预计算的某些条件,我怎样才能安全地转义输入?我使用preparedstatement正是为了这个目的......
  • Prepared statements(或者,更具体地说,使用“?”的参数替换,您可能可以从其他 JDBC 类中获得 - 我不记得了)正是避免 SQL 的正确方法注入攻击。但是(正如我对另一个简单地将 if 语句更改为循环的答案所评论的那样)您所做的就是在准备好的语句上设置参数,然后将其丢弃并创建一个新语句。准备好的语句的 API (正确地)不会让你做你想做的事。
  • @dty - 你有这个链接可以帮助进一步解释这个吗?
  • Marcx 可以通过使用多个 PreparedStatement 来完成一些事情吗?假设已知哪些字段可能会丢失?无论如何,我删除了我的答案。
【解决方案3】:

另一种解决方案是使用 Hibernate Criteria API 使用“更面向对象的方法”,它允许您动态创建查询(典型用途是具有许多参数的搜索查询),但我不知道您使用什么技术堆栈。

【讨论】:

    猜你喜欢
    • 2012-11-21
    • 2016-02-13
    • 1970-01-01
    • 2015-01-09
    • 2016-05-23
    • 2021-07-19
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多