我正在通过查询字符串传递的值准备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时,这就太荒谬了。
是否有更简单的方法可以让它更灵活,以便我知道如何以更好的方式填写所有?
?
答案 0 :(得分:3)
一个例子(评论太长了):
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();
}
答案 1 :(得分:0)
这样的事情可能(只是粗略的代码,但你明白了):
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();
}
答案 2 :(得分:-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();
}