sql >> Base de Datos >  >> RDS >> Database

Cómo crear un objeto ResultSet actualizable y desplazable en JDBC

Al obtener una lista de registros a través de consultas, a menudo necesitamos almacenarlos en un objeto que permita recorrerlos de un lado a otro, actualizándolos según sea necesario. Este artículo ilustra esta técnica comúnmente necesaria en la programación de bases de datos con códigos explícitos y escenarios de ejemplo.

Acerca de Conjunto de resultados

El Conjunto de resultados es una interfaz definida en java.sql paquete. Representa una tabla de datos devueltos por una Declaración objeto. Una Declaración El objeto se utiliza para ejecutar consultas SQL a la base de datos. El objeto ResultSet mantiene un cursor que apunta al registro actual en la tabla de la base de datos. Como resultado, se puede usar de manera efectiva para posicionarse en diferentes filas, de un lado a otro usando primero() , anterior() , siguiente() y último() métodos según los requisitos. Inicialmente, el ResultSet el objeto se coloca en una ubicación antes de la primera fila. Esta es la razón por la que un ResultSet el recorrido siempre comienza de la siguiente manera:

while(resultSet.next()) {

   // ...

}

Tenga en cuenta que el ResultSet el objeto se coloca en la primera fila ejecutando next() método al entrar en el bucle, porque, como ya se ha mencionado, el ResultSet El objeto se encuentra inicialmente en una posición justo antes de la primera fila. Por lo tanto, debe colocarse al menos en la primera fila, por ejemplo, para obtener un registro válido. Puede considerarse como un valor -1 en una posición de matriz a la que apunta un puntero/índice. Primero se debe reubicar al menos en la ubicación 0 para obtener cualquier tipo de valor válido de la matriz.

Ahora, como hemos mencionado, podemos desplazarnos por los registros con la ayuda del ResultSet objeto. Pero, esta habilidad no viene por defecto. El comportamiento predeterminado del ResultSet El objeto es que no es actualizable y el cursor que posee en realidad se mueve en una dirección, solo hacia adelante. Esto significa que podemos iterar a través de los registros solo una vez y solo hacia adelante. Sin embargo, hay formas de hacerlo flexible para que el ResultSet no solo es actualizable sino también desplazable.

Los veremos en un minuto en dos programas separados.

ResultSet desplazable

Primero hagamos el ResultSet objeto desplazable. Desplazable significa que una vez que el ResultSet se ha creado un objeto, podemos recorrer los registros obtenidos en cualquier dirección, hacia adelante y hacia atrás, como queramos. Esto brinda la capacidad de leer el último registro, el primer registro, el siguiente registro y el registro anterior.

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

Salida

  1. Conexión establecida.
  2. Ejecutando consulta SQL...
  3. Objeto ResultSet creado con éxito.
  4. Ahora, comienza el desplazamiento de 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. Eso es todo. Finaliza el desplazamiento de RecordSet.

Tenga en cuenta que el ResultSet desplazable objeto es el resultado de la ejecución de executeQuery() método obtenido a través de la instancia de Statement o Declaración Preparada . El tipo de ResultSet El objeto que nos gusta crear debe declararse explícitamente en la Declaración objeto a través de constantes de tipo scroll definidas.

  • Conjunto de resultados.TYPE_FORWARD_ONLY: Este es el tipo predeterminado.
  • Conjunto de resultados.TYPE_SCROLL_INSENSITIVE: Permite el movimiento de ida y vuelta, pero no es sensible a ResultSet actualizaciones.
  • Conjunto de resultados.TYPE_SCROLL_SENSITIVE: Permite el movimiento de ida y vuelta, pero es sensible a ResultSet actualizaciones.

Se utilizan otras constantes, como CONCUR_READ_ONLY , lo que significa que el ResultSet no es actualizable. Hay otra constante, CONCUR_UPDATABLE , que significa lo contrario, es decir, el ResultSet es actualizable.

Conjunto de resultados actualizable

Creación de un ResultSet actualizable significa que el registro al que apunta no solo es transitable sino también actualizable. Los cambios persistirán inmediatamente en la base de datos y se reflejarán en el ResultSet objeto en tiempo real.

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

El ResultSet actualizable es particularmente útil cuando queremos actualizar ciertos valores después de hacer alguna comparación recorriendo los registros obtenidos. El proceso de creación es similar al del programa anterior, pero el ResultSet las constantes utilizadas aquí son TYPE_SCROLL_SENSITIVE y CONCUR_UPDATABLE .

Conclusión

Al contrario del comportamiento predeterminado del ResultSet, faculta al objeto a tener una mayor flexibilidad. La aplicación puede aprovechar esta funcionalidad no solo para recorrer los registros, sino también para actualizarlos a fin de que puedan brindar un mejor servicio. Aunque el comportamiento estándar de un conjunto de resultados parece bastante ineficiente en comparación con el ResultSet desplazable , tiene su propio uso y por lo tanto es insustituible.