sql >> Databasteknik >  >> RDS >> Database

Hur man skapar ett rullningsbart, uppdateringsbart ResultSet-objekt i JDBC

När vi hämtar en lista med poster genom frågor behöver vi ofta lagra dem i ett objekt som tillåter vandring fram och tillbaka, uppdatera vid behov. Den här artikeln illustrerar denna vanliga teknik i databasprogrammering med explicita koder och exempelscenarier.

Om Resultatuppsättning

Resultatuppsättningen är ett gränssnitt definierat i java.sql paket. Den representerar en tabell med data som returneras av ett uttalande objekt. Ett uttalande objekt används för att köra SQL-frågor till databasen. ResultSet-objektet behåller en markör som pekar på den aktuella posten i databastabellen. Som ett resultat kan den effektivt användas för att positionera på olika rader, fram och tillbaka med first() , föregående() , next() och last() metoder enligt kraven. Till en början, ResultSet objektet är placerat på en plats före den första raden. Detta är anledningen till en Resultatuppsättning traversering börjar alltid enligt följande:

while(resultSet.next()) {

   // ...

}

Observera att Resultatuppsättningen objektet placeras på den första raden genom att köra next() metod när du går in i loopen, eftersom, som redan nämnts, ResultSet objektet är initialt placerat på en position strax före den första raden. Så den måste placeras på åtminstone den första raden, till exempel, för att få en giltig post. Det kan betraktas som ett värde -1 i en arrayposition som en pekare/index pekar på. Den måste först flyttas till åtminstone 0-platsen för att få någon form av giltigt värde från arrayen.

Nu, som vi har nämnt, kan vi bläddra igenom poster med hjälp av Resultatuppsättningen objekt. Men denna förmåga kommer inte som standard. Standardbeteendet för Resultatuppsättningen Objektet är att det inte är uppdateringsbart och markören som den äger rör sig faktiskt i en riktning, bara framåt. Detta innebär att vi bara kan iterera genom posterna en gång och endast i framåtriktning. Det finns dock sätt att göra det flexibelt så att ResultSet är inte bara uppdateringsbar utan även rullningsbar.

Vi kommer att se dem om en minut i två separata program.

Rullbar Resultatuppsättning

Låt oss först göra Resultatuppsättningen objekt rullningsbart. Rullningsbar betyder att när ResultSet objekt har skapats, kan vi gå igenom hämtade poster i vilken riktning som helst, framåt och bakåt, som vi vill. Detta ger möjlighet att läsa den sista posten, första posten, nästa post och föregående 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---------------------------------"+
         "------------------------------------");
   }
}

Utdata

  1. Anslutning upprättad.
  2. Kör SQL-fråga...
  3. ResultSet-objekt skapades framgångsrikt.
  4. Nu börjar en del RecordSet-rullning...
    -------------------------------------------------------------
     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 är allt. RecordSet-rullningen slutar.

Observera att den rullningsbara Resultatuppsättningen objekt är resultatet av exekveringen av executeQuery() metod erhållen genom instansen Statement eller PreparedStatement . Typen av Resultatuppsättning objekt vi vill skapa måste uttryckligen deklareras till Utdraget objekt genom definierade rullningstypkonstanter.

  • Resultatuppsättning.TYPE_FORWARD_ONLY: Detta är standardtypen.
  • Resultatuppsättning.TYPE_SCROLL_INSENSITIVE: Möjliggör rörelser fram och tillbaka, men är okänslig för ResultSet uppdateringar.
  • Resultatuppsättning.TYPE_SCROLL_SENSITIVE: Möjliggör rörelser fram och tillbaka, men är känslig för ResultSet uppdateringar.

Det finns andra konstanter som används, till exempel CONCUR_READ_ONLY , vilket betyder att ResultSet är inte uppdateringsbar. Det finns en annan konstant, CONCUR_UPDATABLE , vilket betyder motsatsen, vilket betyder Resultatuppsättningen är uppdateringsbar.

Uppdaterbar Resultatuppsättning

Skapa en uppdateringsbar Resultatuppsättning innebär att posten som den pekar på inte bara går att passera utan också kan uppdateras. Ändringarna kommer omedelbart att finnas kvar i databasen och återspeglas av Resultatuppsättningen 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---------------------------------"+
               "------------------------------------");
   }
}

Den uppdateringsbara ResultSet är särskilt användbart när vi vill uppdatera vissa värden efter att ha gjort en jämförelse genom att gå fram och tillbaka genom de hämtade posterna. Skapandeprocessen liknar det föregående programmet, men ResultSet konstanter som används här är TYPE_SCROLL_SENSITIVE och CONCUR_UPDATABLE .

Slutsats

I motsats till standardbeteendet för ResultSet, det ger objektet större flexibilitet. Denna funktionalitet kan utnyttjas av applikationen för att inte bara gå igenom poster utan också göra dem uppdateringsbara så att de kan ge en bättre service. Även om standardbeteendet för en resultatuppsättning verkar ganska ineffektivt i jämförelse med den rullningsbara ResultSet , den har sin egen användning och är därför oersättlig.


  1. Konvertera ett datum till en annan tidszon i SQL Server

  2. Vad i helvete är en DTU?

  3. PCI-kompatibilitet för MySQL &MariaDB med ClusterControl

  4. Hur man optimerar COUNT(*) prestanda på InnoDB genom att använda index