提问人:locrizak 提问时间:8/27/2012 最后编辑:Dave L.locrizak 更新时间:8/27/2012 访问量:4411
在 Java 中准备动态语句的正确方法
The proper way to prepare a dynamic Statement in Java
问:
我正在根据通过查询字符串传递的值准备 SQL 语句。(我正在使用 Play! 框架。基本上,我遇到的(不是真正的问题,只是我不太喜欢的东西)是,当我想在SQL字符串中使用并在以后使用动态值设置它们时。?
这是我所拥有的:
String sql = "SELECT * FROM foobar_table WHERE";
if ( foo != 0 )
sql += " AND foo=?";
if ( !bar )
sql += " AND bar=?";
try{
PreparedStatement getStmt = con.prepareStatement(sql);
if ( foo != 0 )
getStmt.setInt(1,foo);
if ( foo != 0 && !bar )
getStmt.setBoolean(2, bar);
else
getStmt.setBoolean(1, bar);
} catch (SQLException e ){
e.printStackTrace();
}
这确实有效,但正如你所看到的,不是很直观。当有 2 个动态值时没关系,但当你达到 5 或 6 时,这只会变得荒谬。
有没有一种更简单的方法可以使其更加灵活,以便我知道如何以更好的方式填写所有内容??
答:
-1赞
mostar
8/27/2012
#1
这个怎么样:
String sql = "SELECT * FROM foobar_table WHERE 1=1";
if ( foo != 0 )
sql += " AND foo=" + foo;
if ( !bar )
sql += " AND bar=" + bar;
try{
PreparedStatement getStmt = con.prepareStatement(sql);
} catch (SQLException e ){
e.printStackTrace();
}
评论
3赞
locrizak
8/27/2012
这难道不会让一切都可以注射吗?准备声明的全部意义在于避免这种情况。
0赞
mostar
8/27/2012
您可以在输入此代码块之前检查参数。你没有提到应该假设变量是不安全的。
0赞
Glenn
8/27/2012
以此为基础,参数化,但也要建立一个对象的 ArrayList 以供以后设置:sql += " AND foo = ?"; paramList.add(foo);
0赞
locrizak
8/27/2012
这就是我在 php 中的做法,但由于 Java 是严格类型的,这将不起作用。 可以是 String、boolean、int、Float 或 doublefoo
0赞
Glenn
8/27/2012
for (Object param : paramList) { preparedStatment.setObject(param); }
3赞
Glenn
8/27/2012
#2
举个例子(太长了,无法评论):
String sql = "SELECT * FROM foobar_table WHERE 1 = 1 ";
ArrayList paramList = new ArrayList();
if ( foo != 0 ) {
sql += " AND foo=?";
paramList.add(foo);
}
if ( !bar ) {
sql += " AND bar=?";
paramList.add(bar);
}
try{
PreparedStatement getStmt = con.prepareStatement(sql);
int index = 1;
for (Object param : paramList) {
getStmt.setObject(index, param);
index++;
}
// execute
} catch (SQLException e ){
e.printStackTrace();
}
评论
0赞
locrizak
8/27/2012
像这样最好..很好,很干净。谢谢
0赞
Dave L.
8/27/2012
#3
也许是这样的东西(只是粗略的代码,但你明白了):
class Param{
final int type;
final Object value;
Param(int type, Object value){
this.type = type;
this.value = value;
}
}
final List<Param> params = new ArrayList<>();
final StringBuilder sql = new StringBuilder("SELECT * FROM bcu_venue_events WHERE 1=1");
int foo = 0;
boolean bar = true;
if (foo != 0){
sql.append(" AND foo=?");
params.add(new Param(Types.INTEGER, foo));
}
if (!bar){
sql.append(" AND bar=?");
params.add(new Param(Types.BOOLEAN, bar));
}
try(Connection conn = null; PreparedStatement getStmt = conn.prepareStatement(sql.toString())) {
for(int i = 0; i < params.size(); i++){
Param p = params.get(i);
getStmt.setObject(i + 1, p.value, p.type);
}
} catch (SQLException e) {
e.printStackTrace();
}
评论