From Gossip@Openhome

Java Gossip: PreparedStatement

Statement主要用於執行靜態的SQL陳述,也就是在執行 executeQuery()、executeUpdate()等方法時,指定內容固定不變的SQL語句字串,每一句SQL只適用於當時的執行,如果您有 些操作只是SQL語句當中某些參數會有所不同,其餘的SQL子句皆相同,則您可以使用java.sql.PreparedStatement。

您可以使用Connection的prepareStatement()方法建立好一個預先編譯(precompile)的SQL語句,當中參數會變動的部份,先指定"?"這個佔位字元,例如:
PreparedStatement stmt = conn.prepareStatement(
    "INSERT INTO message VALUES(?, ?, ?, ?, ?)");
 

要將參數指定給每一個欄位,我們可以使用setInt()、setString()等等方法,例如:
stmt.setString(1, "米小狗");
stmt.setString(2, "dog@mail.com");
stmt.setString(3, "留言吧");
stmt.setString(4, "2004-5-26");
stmt.setString(5, "到此一遊");
stmt.executeUpdate();
stmt.clearParameters();
 

setXXX()方法的第一個參數指定 ? 的位置,而第二個參數為要加入至資料表欄位的值,要讓SQL執行生效,要執行executeQuery()或executeUpdate()方法,使用 setXXX()來設定的參數會一直有效,可以於下一次使用,如果想要清除設定好的參數,可以執行clearParameters()方法。

使用PreparedStatement也可以進行批次處理,直接來看個例子就知道如何使用:
PreparedStatement stmt = conn.prepareStatement(
    "INSERT INTO Users VALUES(?,?, ?)");
 
User[] users = ...;

for(int i=0; i<users.length; i++) {
     stmt.setInt(1, users[i].getID());
     stmt.setString(2, users[i].getName());
     stmt.setString(3, users[i].getPassword());
     stmt.addBatch( );
}
 
stmt.executeBatch();