我希望能更好地理解CallableStatement。
所以我在postgre数据库中有一个存储函数。
从java调用这些函数,其中的参数是用户输入(HTTP POST参数),我不得不担心SQL注入。
在java中执行此操作:
String statementSQL = "SELECT my_function(" + toPostgresString(person.getEmail()) + "," + toPostgresString(person.getPhone()) + "," + toPostgresString(person.getDealType())+ ");";
哪里
private static String toPostgresString(String value) {
if (value == null || value.equals("")) {
return POSTGRES.NULL;
} else {
return "'" + value + "'";
}
}
后一种方法确保所有参数都被视为字符串,但我了解到,当参数是恶意的时,这种解决方案仍然是危险的。
所以我尝试使用CallableStatements,因为据说它们更安全。
CallableStatement statement = connection.prepareCall(" { call my_function( ?, ?, ? ) } ");
statement.setString(1, person.email());
statement.setString(2, person.phone());
statement.setString(3, person.getDealType());
statement.execute();
statement.close();
问题:在这两种情况下,SELECT和CallableStatement的参数都被发送到数据库函数,并在那里作为函数本身定义的数据类型进行处理。CallableStatement只在数据类型不匹配时失败(在声明的函数和statement.set()中)。
当两种情况下参数都被视为字符串(但在“”之间)时,CallableStatement实际上比SELECT更安全。
谢谢。
最佳答案
PreparedStatement
和CallableStatement
都提供设置参数的setXXX
方法。它们实际上并不清理参数,只是在线路上为它们使用二进制类型,因此“在这两种情况下,参数都被当作字符串”部分是错误的。PreparedStatement
还提供了一些次要的性能优势,因为驱动程序实际上会在调用查询足够多次后创建一个服务器端准备好的语句。
除非绝对必要,否则永远不要使用普通的Statement
,并且始终使用setXXX
方法,因为这是它们的用途。
关于java - Java CallableStatement与SELECT有关SQL注入(inject)的问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36859277/