Database
 sql >> Base de données >  >> RDS >> Database

Comment créer un objet ResultSet défilable et actualisable dans JDBC

Lors de la récupération d'une liste d'enregistrements via des requêtes, nous devons souvent les stocker dans un objet qui permet un va-et-vient, en mettant à jour si nécessaire. Cet article illustre cette technique couramment utilisée dans la programmation de bases de données avec des codes explicites et des exemples de scénarios.

À propos de ResultSet

Le Jeu de résultats est une interface définie dans java.sql emballer. Il représente un tableau de données renvoyé par un Statement objet. Une déclaration L'objet est utilisé pour exécuter des requêtes SQL vers la base de données. L'objet ResultSet maintient un curseur pointant vers l'enregistrement en cours dans la table de la base de données. En conséquence, il peut être utilisé efficacement pour se positionner sur différentes lignes, d'avant en arrière en utilisant first() , précédent() , suivant() , et dernier() méthodes selon les besoins. Initialement, le ResultSet l'objet est positionné à un emplacement avant la première ligne. C'est la raison pour laquelle un ResultSet la traversée commence toujours comme suit :

while(resultSet.next()) {

   // ...

}

Notez que le ResultSet l'objet est positionné à la première ligne en exécutant le next() lors de l'entrée dans la boucle, car, comme déjà mentionné, le ResultSet l'objet est initialement situé à une position juste avant la première ligne. Ainsi, il doit être placé au moins sur la première ligne, par exemple, pour obtenir un enregistrement valide. Il peut être considéré comme une valeur -1 dans une position de tableau vers laquelle pointe un pointeur/index. Il doit d'abord être relocalisé au moins à l'emplacement 0 pour obtenir n'importe quel type de valeur valide du tableau.

Maintenant, comme nous l'avons mentionné, nous pouvons faire défiler les enregistrements à l'aide du ResultSet objet. Mais, cette capacité ne vient pas par défaut. Le comportement par défaut du ResultSet objet est qu'il ne peut pas être mis à jour et que le curseur qu'il possède se déplace en fait dans une direction, vers l'avant uniquement. Cela signifie que nous ne pouvons parcourir les enregistrements qu'une seule fois et vers l'avant uniquement. Cependant, il existe des moyens de le rendre flexible afin que le ResultSet n'est pas seulement actualisable mais également défilable.

Nous les verrons dans une minute dans deux programmes distincts.

Défilement ResultSet

Commençons par créer le ResultSet objet défilable. Défilement signifie qu'une fois que le ResultSet objet a été créé, nous pouvons parcourir les enregistrements récupérés dans n'importe quelle direction, en avant et en arrière, comme nous le souhaitons. Cela permet de lire le dernier enregistrement, le premier enregistrement, l'enregistrement suivant et l'enregistrement précédent.

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---------------------------------"+
         "------------------------------------");
   }
}

Sortie

  1. Connexion établie.
  2. Exécution de la requête SQL…
  3. Objet ResultSet créé avec succès.
  4. Maintenant, un défilement de RecordSet commence…
    -------------------------------------------------------------
     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. C'est tout. Fin du défilement de RecordSet.

Notez que le défilement ResultSet l'objet est le résultat de l'exécution de executeQuery() méthode obtenue via l'instance de Statement ou DéclarationPréparée . Le type de ResultSet l'objet que nous aimons créer doit être explicitement déclaré dans la Statement objet par le biais de constantes de type de défilement définies.

  • Ensemble de résultats.TYPE_FORWARD_ONLY : C'est le type par défaut.
  • Ensemble de résultats.TYPE_SCROLL_INSENSITIVE : Active le mouvement de va-et-vient, mais est insensible à ResultSet mises à jour.
  • Ensemble de résultats.TYPE_SCROLL_SENSITIVE : Permet un mouvement de va-et-vient, mais est sensible à ResultSet mises à jour.

Il existe d'autres constantes utilisées, telles que CONCUR_READ_ONLY , ce qui signifie que le ResultSet n'est pas actualisable. Il existe une autre constante, CONCUR_UPDATABLE , ce qui signifie le contraire, c'est-à-dire le ResultSet est modifiable.

Ensemble de résultats modifiable

Créer un ResultSet pouvant être mis à jour signifie que l'enregistrement vers lequel il pointe est non seulement traversable, mais également modifiable. Les modifications seront immédiatement conservées dans la base de données et reflétées par le ResultSet objet en temps réel.

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---------------------------------"+
               "------------------------------------");
   }
}

Le ResultSet modifiable est particulièrement utile lorsque nous voulons mettre à jour certaines valeurs après avoir effectué une comparaison en parcourant les enregistrements récupérés. Le processus de création est similaire au programme précédent, mais le ResultSet les constantes utilisées ici sont TYPE_SCROLL_SENSITIVE et CONCUR_UPDATABLE .

Conclusion

Contrairement au comportement par défaut du ResultSet, il permet à l'objet d'avoir une plus grande flexibilité. Cette fonctionnalité peut être exploitée par l'application non seulement pour parcourir les enregistrements, mais également pour les rendre actualisables afin qu'ils puissent fournir un meilleur service. Bien que le comportement standard d'un jeu de résultats semble assez inefficace par rapport au ResultSet déroulant , il a sa propre utilité et est donc irremplaçable.