如何在Java中创建动态预处理语句?

时间:2012-03-30 12:56:44

标签: java sql prepared-statement

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

5 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:3)

如果您根据用户选择的选项构建查询中的where /和子句,我猜,您已经知道必须对查询进行哪些更改才能获得所需的数据。如果是这种情况,那么您可以创建一个方法,该方法接受用户要求的选项作为方法的参数,该方法构建查询并返回该查询。

//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();

对于这个问题,有一个更为重要的解决方案,但是我们有一个应用程序使用用户的输入查询数据库中的记录以构建查询,并且它在过去两年中一直运行正常。希望有所帮助。

答案 2 :(得分:2)

如果你只想要sql-injection的保护,那么在运行时构建查询是可以的,只要你不插入用户发送到查询中的任何内容(但是如果用户在字段中发送了至少某些东西,则插入子句就可以了)。

表现 - 我不知道。也许DB会缓存准备好的语句,所以如果再次构造完全相同,它会更快,或者不会。我不知道怎么找出来。

答案 3 :(得分:0)

如果您正在使用Hibernate,Criteria Queries API是避免字符串连接以构建SQL查询的好工具。使用普通的JDBC,你必须使用StringBuffer,因为@Jhonatan说。

答案 4 :(得分:-1)

声明一个方法并通过该方法传递userinput。然后根据readystement对象中的输入数据类型使用setStringsetLong