【发布时间】:2013-10-15 16:40:25
【问题描述】:
我们都知道在 Java 中应该使用 PreparedStatments 来避免安全漏洞。
但是,我注意到当使用 LIKE 语句进行“开始于”搜索时,PreparedStatments 可能会导致性能问题。因为该语句是在没有值的情况下编译的,所以驱动程序必须假定通配符可以在任何地方,包括开头,因此它会跳过该列上的任何索引。但是,如果您使用 LIKE 值作为文字来编译语句,它会看到它可以在值上使用列的索引,直到通配符和查询执行良好。
//safe, but prepared statement can't use index on MYCOL
String userInput = "myval%";
statement = conn.prepareStatement("SELECT * FROM MYTABLE WHERE MYCOL LIKE ?");
statement.setString(1, userInput);
rs = statement.executeQuery();
//can use index on MYCOL, but is not safe
statement = conn.createStatement();
rs = statement.executeQuery("SELECT * FROM MYTABLE WHERE MYCOL LIKE '"+userInput+"'");
那么如何在保留索引的同时避免安全漏洞呢?我假设我将不得不尝试清理输入而不是使用 PreparedStatement - 如果是这样,是否存在一个库来正确执行它?或者是否有相同的 java.sql 或(oracle)数据库提示方式告诉准备好的语句它将能够使用值上的索引?
【问题讨论】:
-
为什么不提示数据库使用索引?
-
@YourCommonSense,我确实提到了提示,不是吗。好吧,如果可能的话,我宁愿不使用它们。我的查询是针对可能基于最多 6-7 个不同列的 LIKE 进行选择的搜索。我担心提示会选择错误的索引.....
标签: java sql prepared-statement indexing sql-like