Java 将没有参数的查询传递给PreparedStatement安全吗?

Java 将没有参数的查询传递给PreparedStatement安全吗?,java,jdbc,prepared-statement,sql-injection,Java,Jdbc,Prepared Statement,Sql Injection,我对Java很陌生,所以这肯定是一个愚蠢的问题 我经常读到,在处理被视为字符串的查询时,必须注意SQL注入的风险。我还了解到,使用PreparedStatements是防止此类风险的一种好方法,但它们通常与查询中的位置参数一起使用(用问号?表示) 如果我只有一个没有参数的“常量”查询(即,我的查询中没有要插入的变量),情况会怎样?我还必须在表单中传递查询吗 “从col1=?和col2=?”的表中选择*” 到PreparedStatement以防止SQL注入 或者我可以通过吗 “从col1=123

我对Java很陌生,所以这肯定是一个愚蠢的问题

我经常读到,在处理被视为字符串的查询时,必须注意SQL注入的风险。我还了解到,使用PreparedStatements是防止此类风险的一种好方法,但它们通常与查询中的位置参数一起使用(用问号
表示)

如果我只有一个没有参数的“常量”查询(即,我的查询中没有要插入的变量),情况会怎样?我还必须在表单中传递查询吗
“从col1=?和col2=?”的表中选择*”
到PreparedStatement以防止SQL注入

或者我可以通过吗
“从col1=123和col2=abc的表格中选择*”
?

我有以下代码:

public ResultSet mySelectMethod(String query, Connection conn) {
    ResultSet rset = null;
    try {
        PreparedStatement st = conn.PreparedStatement(query);   //I am unsure about this assignment
        rset = st.executeQuery();
    } catch (SQLException e) {
        System.out.println(e);
    }
    return rset;
}
...
...
// method call:
String myQuery = "SELECT colA FROM table_name WHERE table_id = 192837465";
ResultSet myResultSet = mySelectMethod(myQuery, myConn);

这是安全的还是有任何问题?

因为您没有向查询传递任何参数,所以您没有SQL注入的风险。此外,您的案例不需要
PreparedStatement
。您可以使用
语句

String query = "SELECT * from Table where col1 = 123 and col2 = 'abc'";

try (Statement st = conn.createStatement()) {
    ResultSet rset = stmt.executeQuery(query);

    while (rs.next()) {
        //...
    }
} 

除此之外,正如您在上面的代码中所看到的,您应该尝试使用自动关闭资源的方法。

危险在于将外部输入直接插入到SQL查询中。执行已包含安全值的查询时不存在安全问题。“当处理被视为字符串的查询时SQL注入的风险”风险是当您从网页上的文本框中获取一些外部输入,并直接将其放入字符串中,而您没有这样做。这很好。好的,所以基本上如果没有人将我的方法用于外部输入(我只调用它来执行固定查询),就不会有问题。对吗?谢谢大家!这里的答案很好地回答了这个问题。我真的建议您花点时间看看SQL注入(以及许多其他注入)工作起来有多容易。由于它是一个非常普遍的问题,它是最容易和最常见的攻击向量。这通常很容易预防,但最重要的是:在设计软件时要始终牢记在心。谢谢!!我可以将语句也用于插入/更新/删除吗?或者这只能通过事先准备好的声明才能实现?非常欢迎!您可以使用
插入
更新
删除
语句。