2012-08-26 57 views
0

我正在通過傳遞查詢字符串的值來準備SQL語句。 (我正在使用Play!框架,基本上我遇到的問題(不是真的只是我不太喜歡的問題)是,當我想在SQL字符串中使用?,並在稍後使用動態值設置它們時。在Java中準備動態語句的正確方法

這是我有:

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此只想得到荒謬

有沒有一個更簡單的方法來做到這一點,使它更靈活,以便我知道如何填寫所有?以更好的方式?

回答

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(); 
} 
+0

像這樣最好..很好,乾淨。謝謝 – locrizak

-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

+0

@locrizak - 是的 – david

+0

你可以在輸入這個代碼塊之前檢查參數。你沒有提到變量應該被認爲是不安全的。 – mostar

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(); 
    }