Hier zu später Stunde noch das versprochene verbesserte ExceptionHandling:
Über
das hier:
catch(SQLException sqlEx)
{
while(sqlEx != null) {
System.err.println("SQLException information");
System.err.println("Error msg: " + sqlEx.getMessage());
System.err.println("SQLSTATE: " + sqlEx.getSQLState());
System.err.println("Error code: " + sqlEx.getErrorCode());
sqlEx.printStackTrace();
sqlEx=sqlEx.getNextException();
}
}
Falls es Probleme mit dem SQL gibt, erhält man so alle wichtigen Fehlerinformationen. Über SQLState und ErrorCode bekommt man aus der DB2 Doku direkt raus, woran es hakt. Meistens ist bei mir das SQL-Statement doch nicht so richtig (bei mir zumindest)
Btw. bringt System.gc() fast nie etwas.
Ausserdem solltest du PreparedStatement statt Statement verwenden. Das macht den Code oft sicherer und vielleicht können so auch die Ausführungspfade von SQL-Statements auf DB2 gecached werden (die Regeln habe ich immer noch nicht so richtig verstanden). JDBC läuft immer über sogenanntes "dynamisches SQL" und da wird auf DB2 immer zuerst der "Ausführungsplan" errechnet und das nimmt Zeit in Anspruch. Bei einfachen SQL aber im Milisekundenbereich.
Warum diese komische Konstruktion mit connection noch mal in catch schliessen?
Oben öffnest du eine Datenbank-Connection. Das ist eine knappe Ressource. Wenn nun in dem Code des try-Blocks an irgend einer Stelle eine Exception auftritt, wechselt das Programm direkt in den catch-Block und kommt nie wieder in den try zurück. Die Connection muß aber geschlossen werden. So muß man das eben im catch auch noch machen. Und dieses Statement muß wiederum mit try-catch umgeben werden, da connection.close() eine SQLException wirft.
Das sind all diese kleinen JDBC-Basics.
In der realen Java-Welt ist JDBC Programmierung mittlerweile ziemlich selten. Die Leute benutzen irgendwelche Frameworks und Objekt-Relationalen-Mapper wie Hibernate.
Ich hab hier z.B. ein Framework namens IBAtis SQLMaps und da stehen die ganzen SQL-Queries gar nicht mehr im Source-Code sondern werden per xml definiert:
Sieht ungefähr so aus:
Als Beispiel steht ein solcher sql-query in einer xml-Datei (mit den entsprechenden Datentypen die übergeben und zurückgegeben werden:
<select id="getIdByIdUserAndIdStockDescr"
parameterClass="java.util.HashMap" resultClass="java.lang.Long">
Select ID from STockUser where IDUSER=#idUser# AND IDStockDescr=#idStockDescr#
</select>
Wird dann einfach so in einem sogenannten DataAcces Object aufgerufen und ich spar mir den ganzen restlichen Quatsch. Den Rest macht das Framework. Hier lass ich mir nur eine ID als Long zurückgeben. Ganze Objekte geht aber auch. Auch als Collection.
public StockUser getStockUserByIdUserAndIdStockDescr(long idUser, int idStockDescr) throws IllegalArgumentException {
if (idUser < 0) throw new IllegalArgumentException("Parameter idUser cannot be lower than 0");
if (idStockDescr < 0) throw new IllegalArgumentException("Parameter idStockDescr cannot be lower than 0");
Map params = new HashMap();
params.put("idUser", new Long(idUser));
params.put("idStockDescr", new Long(idStockDescr));
return (StockUser)getSqlMapClientTemplate().queryForObject("getStockUserByIdUserAndIdStockDescr", params);
}
Leider kann man mit Notes solche schönen Sachen nur unter ziemlichen Verrenkungen schwer verwenden.