2012-10-28 68 views
3

我現在有一個方法,現在看起來像下面:查詢清單,準備語句(JDBC)

public void foo(Date date) { 
    PreparedStatement stmt; 
    ResultSet rs; 
    java.sql.Date sDate = new java.sql.Date(date.getTime()); 

    try { 
     String sql = "select * from some_table p where p.start_date <=? and ?<= p.end_date"; 
     stmt = getConnection().preparedStatement(sql); 
     stmt.setDate(1, sDate); 
     stmt.setDate(2, sDate); 
     rs = stmt.executeQuery(); 
     //... 
    } finally { 
     if (rs != null) { rs.close(); } 
     if (stmt != null) { stmt.close(); } 
    } 
} 

現在,而不是傳遞一個Date對象,我想在最新的名單通過(List<Date> dates )。我想我在技術上可以多次調用foo,同時遍歷列表,但有沒有一種方法可以實現這一點,而無需多次調用foo?

+0

我們可以將<=上的多個日期?我猜想查詢應該是IN而不是<=如果你想做範圍查詢,不是嗎?我也可能是錯的。 – kosa

+0

你必須多次調用它 – case1352

+0

迭代是我唯一的選擇嗎? – student

回答

2

不要傳遞單個Date對象,而應考慮將Date對象的ArrayList傳遞給您的foo(...)方法並使用它。

你有幾個選項可以使用。

選項1:通過改變參數

public void foo(ArrayList<Date> dateList) { 
    if(dateList == null) 
     return; 

    PreparedStatement stmt = null; 
    ResultSet rs = null;  
    java.sql.Date sDate = null; 
    try{ 
     stmt = getConnection().preparedStatement("select * from some_table p where p.start_date <=? and ?<= p.end_date"); 

     for(Date date: dateList){ 
      try{ 
       sDate = new java.sql.Date(date.getTime()); 
       stmt.clearParameters(); //Clear current parameter values 
       stmt.setDate(1, sDate); 
       stmt.setDate(2, sDate); 
       rs = stmt.executeQuery(); 

       //perform your operations 
      }finally{ 
       sDate = null; 
       //mange your resultset closing 
      } 
     } 
    }finally{ 
     //your resource management code 
    } 
} 

選項2執行PreparedStatement的你多次:創建一個SQL查詢考慮到你在你的名單已經的日期數,執行此語句,然後使用結果集。

public void foo(ArrayList<Date> dateList) { 
    if(dateList == null) 
     return; 

    PreparedStatement stmt = null; 
    ResultSet rs = null;  
    java.sql.Date sDate = null; 
    StringBuilder builder = new StringBuilder(); 

    try{ 
     //1. Create your dynamic statement 
     builder.append("SELECT * FROM some_table p WHERE \n"); 
     for(int index = 0; index < dateList.length; index++){ 
      if(index > 0) 
       builder.append(" OR \n"); 
      builder.append("(p.start_date <=? and ?<= p.end_date)"); 
     } 

     stmt = getConnection().preparedStatement(builder.toString()); 

     //2. Set the parameters 
     int index = 1; 
     for(Date date: dateList){ 
      try{ 
       sDate = new java.sql.Date(date.getTime()); 
       stmt.setDate(index, sDate); 
       stmt.setDate(index+1, sDate); 
       index += 2; 
      }finally{ 
       sDate = null; 
       //mange your resultset closing 
      } 
     } 

     //3. execute your query 
     rs = stmt.executeQuery(); 

     //4. perform your operations 
    }finally{ 
     builder = null; 
     //your resource management code 
    } 

} 
+1

@alexispigeon - woops,沒有看到混淆。感謝編輯:) – Sujay

0

這是一個只使用一個數據庫調用的解決方案。這不檢查空或空dateList,相反,它假定至少有一個元素。

public void foo(List<Date> dateList) { 
    PreparedStatement stmt; 
    ResultSet rs; 

    try { 
     // Step 1 : build the query string, based on the number of elements in the list 
     StringBuilder sql = new StringBuilder("select * from some_table p where (p.start_date <=? and ?<= p.end_date)"); 
     if (dateList.size() > 1) { 
      for (int i = 1; i < dateList.size(); i++) { 
       sql.append(" or (p.start_date <=? and ?<= p.end_date)"); 
      } 
     } 

     stmt = getConnection().preparedStatement(sql.toString()); 

     // Step 2 : pass the actual list of dates to the query 
     for (int i = 0; i < dateList.size(); i++) { 
      java.sql.Date date = new java.sql.Date(dateList.get(i).getTime()); 
      stmt.setDate((i * 2) + 1, date); 
      stmt.setDate((i * 2) + 2, date); 
     } 

     rs = stmt.executeQuery(); 
     //... 
    } finally { 
     if (rs != null) { rs.close(); } 
     if (stmt != null) { stmt.close(); } 
    } 
}