如何在Java中创建动态准备语句?

如何在Java中创建动态准备语句?,java,sql,prepared-statement,Java,Sql,Prepared Statement,我知道使用准备好的语句有助于避免sql注入。我的问题是,事先准备好的声明通常是静态的。我有一个问题,在运行时根据用户输入构建sql查询的where子句。根据填写的输入字段,我必须将相应的语句添加到where子句中。如何使用准备好的语句实现这一点?我想您可以根据准备好的语句要查询的列动态构建它们,即使用StringBuffer和循环根据所需的列构建它们 为了提高效率,您应该将它们保存在某种内存中查找中。因此,您最终将得到一个映射或其他准备好的语句集合,其中检索键是它们设计用来查询的列。如果您只想防

我知道使用准备好的语句有助于避免sql注入。我的问题是,事先准备好的声明通常是静态的。我有一个问题,在运行时根据用户输入构建sql查询的where子句。根据填写的输入字段,我必须将相应的语句添加到where子句中。如何使用准备好的语句实现这一点?

我想您可以根据准备好的语句要查询的列动态构建它们,即使用StringBuffer和循环根据所需的列构建它们


为了提高效率,您应该将它们保存在某种内存中查找中。因此,您最终将得到一个映射或其他准备好的语句集合,其中检索键是它们设计用来查询的列。

如果您只想防止sql注入,在运行时构造查询是可以的,只要您不在查询中插入任何用户发送的内容(但若用户在字段中至少发送了一些内容,则插入子句是可以的)


性能-我不知道。也许DB会缓存准备好的语句,所以如果您再次构造完全相同的语句,它会更快,或者不会。我不知道如何找到答案。

如果您使用Hibernate,API是一个很好的工具,可以避免字符串连接来构建SQL查询。对于纯JDBC,您必须使用StringBuffer作为@Jhonatan说。

如果您正在构建where/and子句在基于用户选择的选项的查询中,我猜,您已经知道为了获得所需的数据,必须对查询进行哪些更改。如果是这种情况,那么您可以创建一个方法,将用户请求的选项作为该方法的参数,该方法生成查询并返回该参数询问

//something similar to the following
public String buildQuery(int option){
  StringBuilder sb = new StringBuilder();
  sb.append("select fields from table");
  switch(option){
    case 1:
     //build query and append to sb
     sb.append("where clause for option1");
    case 2:
     //build query and append to sb
     sb.append("where clause for option2");
    default:
    // build query using default
    sb.append("default where clause");
  }

  return sb.toString();
}
// create the stored procedure
PreparedStatement ps = conn.prepareStatement(buildQuery(2));
ResultSet rs = ps.executeQuery();
现在,如果需要在查询中使用特定的用户输入值,可以将它们临时存储在列表或映射中,然后进行设置

ps.setString(1,list.get(0));
ps.setString(2,list.get(1));
ResultSet rs = ps.executeQuery();

这个问题可能有一个更简单的解决方案,但是我们有一个应用程序,它使用用户的输入来查询数据库中的记录,并且在过去两年中一直运行良好。希望这能有所帮助。

声明一个方法并通过该方法传递用户输入。然后使用
设置字符串
setLong
取决于preparedstement对象中的输入数据类型。

来自JavaDocs for PreparedStatement“表示预编译SQL语句的对象”基于这一点,我不相信DB会缓存它们,我更愿意自己缓存它们。当然,如果您可以随时对其进行分析的话。但是仅仅实现缓存可能会更快;)根据缓存可以通过连接池来完成。好的,但这意味着我还必须在创建的sql查询中保留参数列表,因为只有使用索引才能添加值。我说的对吗?是的,您需要保留参数列名以在缓存中进行查找,您还需要保留它们的顺序,或者以某种方式(字母?)预测顺序,这样您就知道用查询数据替换哪个“?”。希望这一切都有意义,SQL不是我的第一语言:)我认为进行动态搜索的最好方法是使用存储过程。当试图使用准备好的语句构建查询和参数时,它可能会变得混乱。如果你不使用预先准备好的语句,你很容易受到注入攻击。