我有这段代码,非常标准的东西。它接受java对象中的一些过滤器,并返回与过滤器匹配的所有记录:
class MarkFilters {
Integer idFilter;
Integer userIDFilter;
Integer claimIDFilter;
}
List<Integer> findMarksMatchingFilters(MarkFilters filters) {
String sql = "select id from Mark where 1";
// This has the values to substitute in for the ?'s in the SQL
List<Object> parameters = new LinkedList<Object>();
if (filters.idFilter != null) {
sql += " and id = ?";
parameters.add(filters.idFilter);
}
if (filters.userIDFilter != null) {
sql += " and userID = ?";
parameters.add(filters.userIDFilter);
}
if (filters.claimIDFilter != null) {
sql += " and claimID = ?";
parameters.add(filters.claimIDFilter);
}
return executeSQLWithParameters(sql, parameters);
}我找到了一种应该做同样事情的方法:
List<Integer> findMarksMatchingFilters(MarkFilters filters) {
return executeSQLWithParameters(
"select * from Mark " +
"where (? = NULL or id = ?) " +
"and (? = NULL or userID = ?) " +
"and (? = NULL or claimID = ?) ",
filters.idFilter, filters.idFilter,
filters.userIDFilter, filters.userIDFilter,
filters.claimIDFilter, filters.claimIDFilter);
}因此,例如,如果我输入一个新的MarkFilters(null,null,3),sql语句将是:
select * from Mark
where (NULL = NULL or id = NULL)
and (NULL = NULL or userID = NULL)
and (3 = NULL or claimID = 3)从理论上讲,它将被优化为:
select * from Mark where claimID = 3;我的具体问题是:这种优化真的会发生吗?
我更广泛的问题是:这是一个很好的模式,还是我看不到的缺点?
谢谢!
发布于 2013-04-23 02:38:19
不是的。表达式NULL = NULL的计算结果为false。
你想:
"select * from Mark " +
"where (? is NULL or id = ?) " +
"and (? is NULL or userID = ?) " +
"and (? is NULL or claimID = ?) ",我希望MySQL在编译时计算常量表达式。这意味着在计算之前简化了where子句。但是,我在保证这一点的文档中找不到具体的参考资料。
发布于 2013-04-23 02:48:17
不是一个确切的答案,但我只是找到了一个很好的替代我建议的两种方法:
http://mybatis.github.io/mybatis-3/dynamic-sql.html#chooseWhenOtherwise
https://stackoverflow.com/questions/16159939
复制相似问题