2016-05-13 20 views
1

Wenn PreparedStatements in einem regelmäßigen Java Try-Catch-Block verwendet wird, kann ich die PreparedStatement ändern, um verschiedene Abfragen ausführen, wenn ich brauche, etwa so:Wie verwende ich PreparedStatement zweimal mit Try-with-Resources?

String sqlStatement = "update someTable set someValue = true"; 
try{ 
    PreparedStatement pstmt = con.prepareStatement(sqlStatement); 
    pstmt.executeUpdate(); 

    /* Here I change the query */ 
    String anotherSqlStatement = "update aDifferentTable set something = false"; 
    pstmt = con.prepareStatement(anotherSqlStatement); 
    pstmt.executeUpdate(); 
} 
catch(Exception ex){ 
    ... 
} 

Was ist der richtige Weg Schnupper mit dem dies mit Java zu tun -Ressourcen? Dies ist, was ich versucht habe, aber "Die Ressource PSTMT einer Try-with-Resources-Anweisung kann nicht zugewiesen werden".

try(Connection con = DriverManager.getConnection(someConnection, user, password); 
    PreparedStatement pstmt = con.prepareStatement(sqlStatement)){ 
    ResultSet rs = pstmt.executeQuery(); 
    .... 

    /* Here I attempt to change the query, but it breaks */ 
    String anotherSqlStatement = "select something from someTable"; 
    pstmt = con.prepareStatement(anotherSqlStatement); 
} 
catch(Exception ex){ 
    ... 
} 

Ich will nicht wieder die Variable erklären, verstehe ich, dass der Zweck des Try-mit-Ressourcen besiegen würde, ich will nur es auf etwas anderes übertragen. Was ist der richtige Weg?

+2

Ich bin nicht sicher, dass dies ein Duplikat ist; Diese Frage * versucht * Aufgaben zu erledigen, er versucht nur mit mehr als einer Ressource. – chrylis

+0

Allgemeiner gesagt, niemals eine Variable für einen semantisch unterschiedlichen Zweck wiederverwenden. Es ist verwirrend und eine gute Möglichkeit, Bugs einzuführen. Unveränderlichkeit ist dein Freund. – AjahnCharles

Antwort

3

Überlegen Sie, was passieren würde, wenn Java Ihnen dies erlauben würde. Wenn Sie neu zuweisen, was pstmt referenziert, wird pstmt nach der Ausführung des ersten PreparedStatement auf das zweite PreparedStatement verweisen. Die close-Methode wird nur aufgerufen, auf was pstmt sich an dem Punkt bezieht, an dem der Block fertig ausgeführt wird, so dass close nie beim ersten PreparedStatement aufgerufen wird.

Statt verschachtelte try-mit-Ressourcen Blöcke:

try (Connection con = DriverManager.getConnection(someConnection, user, password)) { 
    try (PreparedStatement pstmt = con.prepareStatement(sqlStatement)) { 
     pstmt.executeUpdate(); 
    } 

    try (PreparedStatement pstmt = con.prepareStatement(anotherSqlStatement)) { 
     pstmt.executeUpdate();    
    } 
} 

Auf diese Weise gibt es zwei pstmt lokale Variablen in verschiedenen Bereichen. Die erste PreparedStatement wird geschlossen, bevor die zweite beginnt.

+0

Das zweite Beispiel in der Frage verwendet ein ResultSet ... Vergessen Sie nicht, das in die try-with-resources-Klausel aufzunehmen (es ist auch ein AutoCloseable). @Nathan Ich weiß nicht, ob du das in deinem Beispiel zeigen wolltest? – AjahnCharles