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

Sådan opretter du et rullebart, opdaterbart ResultSet-objekt i JDBC

Når vi henter en liste over poster gennem forespørgsler, er vi ofte nødt til at gemme dem i et objekt, der tillader traversering frem og tilbage, opdatering efter behov. Denne artikel illustrerer denne almindeligt nødvendige teknik i databaseprogrammering med eksplicitte koder og eksempelscenarier.

Om Resultatsæt

Resultatsættet er en grænseflade defineret i java.sql pakke. Det repræsenterer en tabel med data, der returneres af en erklæring objekt. En erklæring objekt bruges til at udføre SQL-forespørgsler til databasen. ResultSet-objektet bevarer en markør, der peger på den aktuelle post i databasetabellen. Som et resultat kan den effektivt bruges til at placere på forskellige rækker frem og tilbage ved hjælp af first() , previous() , next() , og last() metoder efter krav. Indledningsvis er Resultatsæt objekt er placeret på et sted før den første række. Dette er grunden til et Resultatsæt traversering begynder altid som følger:

while(resultSet.next()) {

   // ...

}

Bemærk, at Resultatsæt objekt er placeret i den første række ved at udføre next() metode, når du går ind i løkken, fordi, som allerede nævnt, ResultSet objektet er oprindeligt placeret på en position lige før den første række. Så den skal som minimum placeres på første række, for eksempel for at få en gyldig post. Det kan betragtes som en værdi -1 i en matrixposition, som en pointer/indeks peger på. Det skal først flyttes til mindst 0-placeringen for at få nogen form for gyldig værdi fra arrayet.

Nu, som vi har nævnt, kan vi rulle gennem poster ved hjælp af Resultatsæt objekt. Men denne evne kommer ikke som standard. Standardadfærden for Resultatsæt Objektet er, at den ikke kan opdateres, og den markør, den ejer, bevæger sig faktisk i én retning, kun fremad. Det betyder, at vi kun kan iterere gennem posterne én gang og kun i fremadgående retning. Der er dog måder at gøre det fleksibelt, så Resultatsæt kan ikke kun opdateres, men kan også rulles.

Vi ser dem om et minut i to separate programmer.

Rulbart Resultatsæt

Lad os først lave Resultatsættet objekt, der kan rulles. Rulbar betyder, at når Resultatsæt objektet er blevet oprettet, kan vi krydse gennem hentede poster i enhver retning, frem og tilbage, som vi vil. Dette giver mulighed for at læse den sidste post, første post, næste post og den forrige post.

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

Output

  1. Forbindelse oprettet.
  2. Udfører SQL-forespørgsel...
  3. ResultSet-objekt blev oprettet.
  4. Nu starter noget RecordSet-rulning...
    -------------------------------------------------------------
     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. Det er alt. RecordSet-rulning slutter.

Bemærk, at det rulbare Resultatsæt objekt er resultatet af udførelsen af ​​executeQuery() metode opnået gennem forekomsten af ​​Statement eller Prepared Statement . Typen Resultatsæt objekt, vi gerne vil oprette, skal udtrykkeligt erklæres til erklæringen objekt gennem definerede rulletypekonstanter.

  • Resultatsæt.TYPE_FORWARD_ONLY: Dette er standardtypen.
  • Resultatsæt.TYPE_SCROLL_INSENSITIVE: Aktiverer bevægelse frem og tilbage, men er ufølsom over for Resultatsæt opdateringer.
  • Resultatsæt.TYPE_SCROLL_SENSITIVE: Aktiverer bevægelse frem og tilbage, men er følsom over for Resultatsæt opdateringer.

Der er andre konstanter brugt, såsom CONCUR_READ_ONLY , hvilket betyder, at Resultatsæt kan ikke opdateres. Der er en anden konstant, CONCUR_UPDATABLE , hvilket betyder det modsatte, hvilket betyder Resultatsæt kan opdateres.

Opdaterbart Resultatsæt

Oprettelse af et opdaterbart Resultatsæt betyder, at posten, den peger på, ikke kun kan gennemløbes, men også kan opdateres. Ændringerne vil øjeblikkeligt blive fastholdt i databasen og afspejlet af Resultatsættet objekt i realtid.

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

Det opdaterbare Resultatsæt er især nyttig, når vi ønsker at opdatere visse værdier efter at have foretaget en sammenligning ved at gå frem og tilbage gennem de hentede poster. Oprettelsesprocessen ligner det foregående program, men Resultatsæt konstanter brugt her er TYPE_SCROLL_SENSITIVE og CONCUR_UPDATABLE .

Konklusion

I modsætning til standardadfærden for Resultatsæt, det giver objektet større fleksibilitet. Denne funktionalitet kan udnyttes af applikationen til ikke kun at gå gennem poster, men også gøre dem opdaterbare, så de kan yde en bedre service. Selvom standardadfærd for et resultatsæt virker ret ineffektivt i sammenligning med det rulbare Resultatsæt , den har sin egen brug og er derfor uerstattelig.


  1. Sådan bruges SQL Server HierarchyID gennem nemme eksempler

  2. Drop udenlandsk nøgle uden at kende navnet på begrænsningen?

  3. Konfiguration af AlwaysOn Availability Groups på SQL Server

  4. Brug TYPE_NAME() til at få navnet på en datatype i SQL Server