2012-09-28 18 views
5

sto autenticato utente Likeposso usare lo stesso JDBC collegamento, affermazione e di risultati per eseguire due query in JDBC

public static boolean login(DataManager dataManager, String userName, String password) {  
    boolean authenticated = false;  
    Connection connection = dataManager.getConnection();   
    if (connection != null) {   
     try {       
      Statement s = connection.createStatement(); 
      String sql = "query";     
      try {     
       ResultSet rs = s.executeQuery(sql);          
       try {      
        while (rs.next()) {        
         String group_code = rs.getString(1); 
         String orgaunit = rs.getString(2); 

         authenticated = true;        
        } //end of while()      
       } finally {      
        rs.close();      
       }     
      } finally { 
       s.close();     
      } 

     } catch(SQLException e) {    
      //System.out.println("Could not login from dataabse:" + e.getMessage());     
     } finally {    
      dataManager.putConnection(connection);       
     }     
    } //end of if (connection != null)  
    return authenticated;  
} //end of login() 

sto chiudendo la connessione in dataManager.putConnection(connection). Voglio chiedere una volta che l'utente ottiene il login, quindi devo aggiornare lo stato dell'utente e mantenere la cronologia del registro. Posso usare qualcosa di simile

try { 
    Statement s = connection.createStatement(); 
    String sql = "query";     
    try {      
     ResultSet rs = s.executeQuery(sql);         
     try { 
      while (rs.next()) {       
       String group_code = rs.getString(1);             
       authenticated = true;        
      } //end of while() 

      if (autherntcated == true) { 
       sql = "query2(update status)"; 
       rs = s.executeQuery(sql); 

       while (rs.next()) { 
        //dos tuff 
       } 

       sql = "anotherQuery"; 
       rs = s.executeQuery(sql); 
       while (rs.next()) { 
        //do stuff 
       } 

      } 

     } finally {      
      rs.close();      
     }      
    } finally { 
     s.close();     
    }     
} catch(SQLException e) { 
    //System.out.println("Could not login from dataabse:" + e.getMessage()); 
} finally {    
    dataManager.putConnection(connection);       
} 

significa usare stessa connessione, stessa affermazione e lo stesso gruppo di risultati eseguire altre query o è un approccio sbagliato?

Grazie.

Modifica ------------------------------------------- -------------------

if (connection != null) { 
    try { 
     String sql = "query"; 
     PreparedStatement prepStatement = connection.prepareStatement(sql); 
     try { 
      ResultSet rs = prepStatement.executeQuery(sql);     
      try { 
       while (rs.next()) { 
        String group_code = rs.getString(1); 
        authenticated = true; 
       } //end of while() 
      } finally {      
       rs.close();      
      } 
     } finally { 
      prepStatement.close();     
     } 

     /// Addition 
     if (authenticated == true) { 
      updateUser(connection, userName); 
     } 
    } catch(SQLException e) { 
     //System.out.println("Could not login from dataabse:" + e.getMessage()); 
    } finally { 
     dataManager.putConnection(connection); 
    } 
} //end of if (connection != null) 

metodo di aggiornamento:

private static void updateUser(Connection connection, String userName) { 

    try { 
     String sql = "UPDATE users SET status_code = 'A' WHERE login_id = '" + userName + "'";  
     PreparedStatement prepStatement = connection.prepareStatement(sql); 
     try { 
      int numberOfRowsUpdated = prepStatement.executeUpdate(sql);     
     } finally { 
      prepStatement.close();     
     } 

     maintainHistory(connection); 

    } catch(SQLException e) { 
    //System.out.println("Could not login from dataabse:" + e.getMessage()); 
    } 

} //end of updateUser() 

maintainHistory:

private static void maintainHistory(Connection connection) { 

    try { 
     String sql = "INSERT INTO auditlog_user_logins(user_code,logintime,prstid) VALUES();"; 
     PreparedStatement prepStatement = connection.prepareStatement(sql);   
     try {    
      int numberOfRowsUpdated = prepStatement.executeUpdate(sql);     

     } finally { 

     prepStatement.close();     

     } 

    } catch(SQLException e) { 

     //System.out.println("Could not login from dataabse:" + e.getMessage()); 

    } 

} //end of maintainHistory() 

risposta

1

vorrei suggerire il riutilizzo connessione perché stabilita connessione ishing ogni volta che stai cercando di interrogare il tuo database, forse un overhead performace.

Per quanto riguarda le istruzioni, suggerirei di passare a PreparedStatement. Non sono solo memorizzati nella cache, ma un buon modo per proteggersi dalle iniezioni SQL. Quindi costruisci la tua domanda in anticipo, eseguili e alla fine chiudili quando hai finito. Riutilizzare PreparedStatement significherebbe sostituire i valori dei parametri per lo stesso PreparedStatement ed eseguire lo stesso.

Così, per esempio, se hai un PreparedStatement simile:

PreparedStatement preparedStatement = connection.prepareStatement("SELECT [col_names] from [table_name] where [col_1_value] = ? and [col_2_value] = ?") 

In questo caso, è possibile riutilizzare gli stessi PreparedStatement più volte da solo sostituendo i nuovi valori per i parametri. In generale, per il tuo caso avrai più PreparedStatements. Dal momento che queste istruzioni sono memorizzate nella cache, non avranno un grande impatto sulle prestazioni quando si esegue lo stesso.

Ecco un buon tutorial per farvi PreparedStatement nel caso in cui hai bisogno di uno: "Using Prepared Statements"

ResultSets - beh io non vedo come è possibile riutilizzarlo. Chiudila come e quando hai finito con loro. Come per il Javadoc:

Un oggetto ResultSet si chiude automaticamente quando l'oggetto Statement che lo ha generato è chiuso, ri-eseguito, o utilizzata per recuperare il successivo risultato di una sequenza di risultati multipli.

Tuttavia, assicurarsi di chiudere la connessione dopo aver finito di usarlo. La riutilizzabilità è una buona cosa, ma la cattiva gestione delle risorse non è

+0

Intendete dire che posso chiudere Statement e ResultSet. Voglio dire che una volta che chiudo l'istruzione e ResultSet, quindi utilizzare l'aggiornamento e un'altra query nello stesso modo e quindi chiudere la connessione al database 'dataManager.putConnection (connessione); '. È? – Basit

+0

@Basit: aggiornata la mia risposta per includere ulteriori informazioni. Idealmente vorrai riutilizzare l'oggetto * connessione *. ResultSet non ha senso e, come ho specificato, vorrei suggerire lo spostamento da * Dichiarazione * a * * PreparedStatement – Sujay

+0

Come quando ho CREATE 'Statement s = connection.createStatement();' Poi devo per chiuderla. Devo anche chiudere la PreparedStatement nello stesso modo in cui sto facendo la Dichiarazione? Per prima cosa sto creando una dichiarazione usando la connessione, quindi ottieni 'ResultSet' usando' s.executeQuery (query) ', quindi esegui il ciclo attraverso il set di risultati. Come posso sostituirlo con PreparedStatement? – Basit

4

posso usare stessa connessione JDBC, dichiarazione

Sì. Puoi riutilizzarli prima della chiusura.

e di risultati

No. La domanda non ha senso. Il set di risultati è il risultato dell'esecuzione di una query o di un aggiornamento. Non si tratta di riutilizzarlo. Immagino che sia necessario chiudere il set di risultati precedente prima di eseguire la query o l'aggiornamento successivo.

+0

ho modificato il mio codice, l'ho fatto nella parte destra maniera ? – Basit

+0

Sembra OK ma non stai riutilizzando alcun 'Statement' o' PreparedStatement' lì, non che tu abbia apparentemente bisogno di farlo. – EJP

0

con risposta caso di test diverso con stessa domanda.

Posso usare lo stesso JDBC connessione, Statement e ResultSet per eseguire due query in JDBC

Non possiamo riutilizzare Connection, Statement e ResultSet parallelamente o concomitante come segue:

Connection con = databaseConnector.getConnection(); 
PreparedStatement stmt1=con.prepareStatement("select * from emp"); 
ResultSet rs1=stmt.executeQuery(); 
while(rs1.next()){ // get SQLException in second iteration 
System.out.println(rs1.getInt(1)+" "+rs1.getString(2)); 
    //As soon as you execute the following query, the previous Statement and ResultSet are implicitly closed. 
    // to resolve we the problem, we should not use the above used Connection. We have to use new Connection. 
    PreparedStatement stmt2=con.prepareStatement("select * from address"); 
    ResultSet rs2=stmt2.executeQuery(); 
    System.out.println(rs2.getString(1)+" "+rs2.getString(2)); 

} 
  • La chiusura di Connection chiude un Statement, quando Statement chiude implicitamente anche ResultSet.
  • La chiusura di Statement chiude un ResultSet ma non Connessione.
  • chiusura di un ReultSet si chiude soltanto, non Statement.
  • Per impostazione predefinita, è possibile aprire solo uno ResultSet per Statement allo stesso tempo.

Best Practice:

  • connessioni non sono thread-safe, in modo da condividere tra le richieste non è una buona idea.
  • Apertura di una connessione DB è un costoso, dovrebbe utilizzare un ConnectionPool per le connessioni di condivisione.
  • Chiudi ResultSet non appena finisci di lavorare con ResultSet.