Database
 sql >> Database >  >> RDS >> Database

Come creare un oggetto ResultSet scorrevole e aggiornabile in JDBC

Quando si recupera un elenco di record tramite query, spesso è necessario archiviarli in un oggetto che consenta l'attraversamento avanti e indietro, aggiornandosi secondo necessità. Questo articolo illustra questa tecnica comunemente necessaria nella programmazione di database con codici espliciti e scenari di esempio.

Informazioni su ResultSet

Il ResultSet è un'interfaccia definita in java.sql pacchetto. Rappresenta una tabella di dati restituiti da un Dichiarazione oggetto. Una Dichiarazione oggetto viene utilizzato per eseguire query SQL al database. L'oggetto ResultSet mantiene un cursore che punta al record corrente nella tabella del database. Di conseguenza, può essere efficacemente utilizzato per posizionarsi su righe diverse, avanti e indietro usando first() , precedente() , successivo() e last() modalità secondo i requisiti. Inizialmente, il ResultSet l'oggetto è posizionato in una posizione prima della prima riga. Questo è il motivo per un ResultSet l'attraversamento inizia sempre come segue:

while(resultSet.next()) {

   // ...

}

Nota che il ResultSet l'oggetto viene posizionato alla prima riga eseguendo next() metodo quando si entra nel ciclo, perché, come già accennato, il ResultSet l'oggetto si trova inizialmente in una posizione appena prima della prima riga. Quindi, deve essere inserito almeno nella prima riga, ad esempio, per ottenere un record valido. Può essere considerato come un valore -1 in una posizione di matrice a cui punta un puntatore/indice. Deve essere prima riposizionato almeno nella posizione 0 per ottenere qualsiasi tipo di valore valido dall'array.

Ora, come accennato, possiamo scorrere i record con l'aiuto del ResultSet oggetto. Ma questa capacità non viene per impostazione predefinita. Il comportamento predefinito di ResultSet l'oggetto è che non è aggiornabile e il cursore che possiede si sposta effettivamente in una direzione, solo in avanti. Ciò significa che possiamo scorrere i record solo una volta e solo in avanti. Tuttavia, ci sono modi per renderlo flessibile in modo che il ResultSet non è solo aggiornabile ma anche scorrevole.

Li vedremo tra un minuto in due programmi separati.

Scorrimento ResultSet

Per prima cosa creiamo il ResultSet oggetto scorrevole. Scorribile significa che una volta ResultSet l'oggetto è stato creato, possiamo attraversare i record recuperati in qualsiasi direzione, avanti e indietro, a nostro piacimento. Ciò fornisce la possibilità di leggere l'ultimo record, il primo record, il record successivo e il record precedente.

package org.mano.example;
import java.sql.*;
public class App
{
   static final String JDBC_DRIVER =
      "com.mysql.cj.jdbc.Driver";
   static final String DB_URL =
      "jdbc:mysql://localhost:3306/employees";
   static final String USER = "root";
   static final String PASS = "secret";
   static final String SQL =
      "SELECT * FROM employees ORDER BY first_name";

   public static void main( String[] args )
   {
      Connection connection = null;
      ResultSet rs = null;
      try {
         Class.forName(JDBC_DRIVER);
         connection = DriverManager.getConnection
            (DB_URL, USER, PASS);
         System.out.println("n1. Connection established");
      }catch(Exception ex) {
         ex.printStackTrace();
      }

      try (PreparedStatement pstmt =
            connection.prepareStatement(SQL,
         ResultSet.TYPE_SCROLL_INSENSITIVE,
         ResultSet.CONCUR_READ_ONLY);){
            System.out.println("n2.
               Executing SQL query...");
            rs = pstmt.executeQuery();
            System.out.println("n3.
               ResultSet object created successfully.");
            System.out.println("n4.
               Now some RecordSet scrolling starts...");

            rs.first();
            show(rs);
            rs.last();
            show(rs);
            rs.previous();
            rs.previous();
            show(rs);
            rs.next();
            show(rs);

            System.out.println("nn5. That's all.
               RecordSet scrolling ends.");
      }catch(SQLException ex){
         ex.printStackTrace();
      }finally{
         try {
            connection.close();
         }catch(SQLException ex){
         }
      }
   }
   public static void show(ResultSet rs) throws
         SQLException{
      System.out.printf
         ("n--------------------------------"+
            "-------------------------------------");
      System.out.printf("n%7d | %10s | %10s | %s
         | %s | %s ",rs.getLong("emp_no"),
         rs.getString("first_name"),
         rs.getString("last_name"),
         rs.getDate("birth_date").toString(),
         rs.getDate("hire_date"),
         rs.getString("gender"));
      System.out.printf
         ("n---------------------------------"+
         "------------------------------------");
   }
}

Uscita

  1. Connessione stabilita.
  2. Esecuzione della query SQL...
  3. Oggetto ResultSet creato correttamente.
  4. Ora, inizia lo scorrimento di RecordSet...
    -------------------------------------------------------------
     497615 |  Aamer  |  McDermid   | 1954-11-18 | 1985-04-24 | M
    -------------------------------------------------------------
    -------------------------------------------------------------
     484995 |  Zvonko |  Lakshmanan | 1964-11-04 | 1992-12-04 | M
    -------------------------------------------------------------
    -------------------------------------------------------------
     482000 |  Zvonko |  Cannata    | 1960-11-23 | 1986-08-13 | M
    -------------------------------------------------------------
    -------------------------------------------------------------
     483497 |  Zvonko |  Pollacia   | 1961-12-26 | 1985-08-01 | M
    -------------------------------------------------------------
    
  5. Questo è tutto. Lo scorrimento del RecordSet termina.

Nota che il ResultSet a scorrimento oggetto è il risultato dell'esecuzione di executeQuery() metodo ottenuto tramite l'istanza di Statement o PreparedStatement . Il tipo di ResultSet l'oggetto che ci piace creare deve essere esplicitamente dichiarato nella Dichiarazione oggetto tramite costanti di tipo scroll definite.

  • ResultSet.TYPE_FORWARD_ONLY: Questo è il tipo predefinito.
  • ResultSet.TYPE_SCROLL_INSENSITIVE: Consente il movimento avanti e indietro, ma non è sensibile a ResultSet aggiornamenti.
  • ResultSet.TYPE_SCROLL_SENSITIVE: Consente il movimento avanti e indietro, ma è sensibile a ResultSet aggiornamenti.

Sono utilizzate altre costanti, come CONCUR_READ_ONLY , il che significa che il ResultSet non è aggiornabile. C'è un'altra costante, CONCUR_UPDATABLE , che significa l'opposto, ovvero il ResultSet è aggiornabile.

Aggiornabile ResultSet

Creazione di un ResultSet aggiornabile significa che il record a cui punta non solo è attraversabile ma anche aggiornabile. Le modifiche verranno immediatamente mantenute nel database e riflesse nel ResultSet oggetto in tempo reale.

package org.mano.example;
import java.sql.*;
public class App
{
   static final String JDBC_DRIVER =
      "com.mysql.cj.jdbc.Driver";
   static final String DB_URL =
      "jdbc:mysql://localhost:3306/employees";
   static final String USER = "root";
   static final String PASS = "secret";
   static final String SQL =
      "SELECT * FROM employees WHERE emp_no = ?";
   public static void main( String[] args )
   {
      Connection connection = null;
      ResultSet rs = null;
      long emp_no = 484995;
      try {
         Class.forName(JDBC_DRIVER);
         connection = DriverManager.getConnection
            (DB_URL, USER, PASS);
         System.out.println("n1.
            Connection established");
      }catch(Exception ex) {
         ex.printStackTrace();
      }
      try(PreparedStatement pstmt =
            connection.prepareStatement(SQL,
         ResultSet.TYPE_SCROLL_SENSITIVE,
         ResultSet.CONCUR_UPDATABLE);){
            pstmt.setLong(1,emp_no);
            System.out.println("n2.
               Executing SQL query...");
            rs = pstmt.executeQuery();
            System.out.println("n3.
               ResultSet object created successfully.");
            while(rs.next()){
               show(rs);
               String fname = rs.getString("first_name");
               System.out.println("n4.
                  Updating name "+fname+" to Subham");
               rs.updateString("first_name", "Subham");
               rs.updateRow();
            }
            System.out.println("nn5.
               Record updated. See below.");
            rs.previous();
            show(rs);
      }catch(SQLException ex){
         ex.printStackTrace();
      }finally{
      try {
         rs.close();
         connection.close();
      }catch(SQLException ex){
      }
      }
   }
   public static void show(ResultSet rs)
         throwsSQLException{
      System.out.printf
         ("n--------------------------------"+
            "-------------------------------------");
      System.out.printf("n%7d | %10s | %10s | %s
            | %s | %s ",rs.getLong("emp_no"),
         rs.getString("first_name"),
         rs.getString("last_name"),
         rs.getDate("birth_date").toString(),
         rs.getDate("hire_date"),
         rs.getString("gender"));
         System.out.printf
            ("n---------------------------------"+
               "------------------------------------");
   }
}

Il ResultSet aggiornabile è particolarmente utile quando vogliamo aggiornare determinati valori dopo aver eseguito un confronto attraversando avanti e indietro i record recuperati. Il processo di creazione è simile al programma precedente, ma il ResultSet le costanti usate qui sono TYPE_SCROLL_SENSITIVE e CONCUR_UPDATABLE .

Conclusione

Contrariamente al comportamento predefinito di ResultSet consente all'oggetto di avere una maggiore flessibilità. Questa funzionalità può essere sfruttata dall'applicazione non solo per attraversare i record, ma anche per renderli aggiornabili in modo che possano fornire un servizio migliore. Sebbene il comportamento standard di un set di risultati sembri piuttosto inefficiente rispetto al ResultSet scorrevole , ha un suo uso e quindi è insostituibile.