我正在开发一个经常访问数据库的 portlet。我必须以某种方式指定查询,这提供了过滤作为对用户输入的反应的可能性。目前用于过滤的参数是两个,但这个数字将来会增加。
目前,我的构造对于所有输入都运行良好,但是,我认为我没有以正确/有效的方式进行操作,因为我不使用准备好的语句,而只是手动构造查询。
这是我的代码示例(serviceFilter是一个 arrayList 并且typeFlag是一个字符串)
private String prepareQuery() {
String query = "SELECT * from messages ";
// check filters
if (!typeFlag.equals("ALL")) {
if (typeFlag.equals("XML")) {
query += "WHERE type='" + TYPE_XML + "'";
} else {
query += "WHERE type='" + TYPE_JAVA + "'";
}
}
// lets see if user specifies some service filtering
if (serviceFilter.size() > 0) {
if (!typeFlag.equals("ALL")) {
query += " AND (";
} else {
query += " WHERE (";
}
for (int i = 0; i < serviceFilter.size(); i++) {
if (i>0) {
query += " OR ";
}
String service = serviceFilter.get(i);
System.out.println("Filter: " + service);
query += "sender='" + service + "' OR receiver='" + service + "'";
}
query += ")";
}
query += " ORDER BY id DESC LIMIT " + String.valueOf(limit);
System.out.println(query);
return query;
}
第一个问题是,这无法防止 SQL 注入(这不会是一个大问题,因为所有输入都来自复选框和滚动条,因此用户实际上并没有输入任何内容)。我不确定如何在这里使用准备好的语句,因为我的 arrayList 的数量可能很长,并且每个查询都会发生变化。
由于这个事实,查询本身可能会变得很长。这是一个仅针对两个参数的查询示例(想象一下 20 个项目):
SELECT * from messages WHERE (sender='GreenServiceESB#GreenListener' OR receiver='GreenServiceESB#GreenListener' OR sender='queue/DeadMessageQueue' OR receiver='queue/DeadMessageQueue') ORDER BY id DESC LIMIT 50
所以基本上,我的问题是:这是构建我的查询的有效方法(可能不是,对吧)?你会建议什么方法?
PS:我正在使用 JDBC 连接到 db 并执行查询,如果它在任何方面都很重要......
感谢您的任何提示!