Při načítání seznamu záznamů pomocí dotazů je často potřebujeme uložit do objektu, který umožňuje procházení tam a zpět a aktualizaci podle potřeby. Tento článek ilustruje tuto běžně potřebnou techniku v databázovém programování pomocí explicitních kódů a příkladů scénářů.
O Sada výsledků
Sada výsledků je rozhraní definované v java.sql balík. Představuje tabulku dat vrácených Výpisem objekt. Prohlášení objekt se používá k provádění SQL dotazů do databáze. Objekt ResultSet udržuje kurzor ukazující na aktuální záznam v tabulce databáze. V důsledku toho jej lze efektivně použít k umístění na různé řádky, tam a zpět pomocí first() , předchozí() , další() a poslední() metody dle požadavků. Zpočátku Sada výsledků objekt je umístěn na místo před první řadou. To je důvod, proč Sada výsledků procházení vždy začíná následovně:
while(resultSet.next()) { // ... }
Všimněte si, že Sada výsledků objekt se umístí na první řádek provedením next() metoda při vstupu do smyčky, protože, jak již bylo zmíněno, ResultSet objekt je zpočátku umístěn na pozici těsně před první řadou. Musí být tedy umístěn alespoň na první řádek, například pro získání platného záznamu. Může být považována za hodnotu -1 v pozici pole, na kterou ukazuje ukazatel/index. Aby bylo možné z pole získat jakoukoli platnou hodnotu, musí být nejprve přemístěno alespoň do polohy 0.
Nyní, jak jsme zmínili, můžeme procházet záznamy pomocí ResultSet objekt. Tato schopnost však není standardně dostupná. Výchozí chování ResultSet Objekt je v tom, že není aktualizovatelný a kurzor, který vlastní, se ve skutečnosti pohybuje jedním směrem, pouze dopředu. To znamená, že můžeme iterovat záznamy pouze jednou a pouze směrem dopředu. Existují však způsoby, jak to udělat flexibilní tak, aby ResultSet je nejen aktualizovatelný, ale také rolovatelný.
Uvidíme je za minutu ve dvou samostatných programech.
Posouvatelná Sada výsledků
Nejprve vytvoříme Sada výsledků objekt rolovatelný. Posouvací znamená, že jakmile Sada výsledků Pokud byl objekt vytvořen, můžeme procházet načtenými záznamy libovolným směrem, vpřed i vzad, jak chceme. To poskytuje možnost číst poslední záznam, první záznam, další záznam a předchozí záznam.
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---------------------------------"+ "------------------------------------"); } }
Výstup
- Připojení navázáno.
- Provádění dotazu SQL…
- Objekt ResultSet byl úspěšně vytvořen.
- Nyní se spustí posouvání sady 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 -------------------------------------------------------------
- To je vše. Posouvání sady záznamů končí.
Všimněte si, že posuvná Sada výsledků objekt je výsledkem provedení executeQuery() metoda získaná prostřednictvím instance Statement nebo PreparedStatement . Typ Sada výsledků objekt, který chceme vytvořit, musí být výslovně deklarován v Prohlášení objekt prostřednictvím definovaných konstant typu rolování.
- ResultSet.TYPE_FORWARD_ONLY: Toto je výchozí typ.
- ResultSet.TYPE_SCROLL_INSENSITIVE: Umožňuje pohyb tam a zpět, ale není citlivý na ResultSet aktualizace.
- ResultSet.TYPE_SCROLL_SENSITIVE: Umožňuje pohyb tam a zpět, ale je citlivý na ResultSet aktualizace.
Používají se i další konstanty, například CONCUR_READ_ONLY , což znamená, že Sada výsledků není aktualizovatelný. Existuje další konstanta, CONCUR_UPDATABLE , což znamená opak, tedy Sada výsledků je aktualizovatelné.
Aktualizovatelná Sada výsledků
Vytvoření aktualizovatelné sady výsledků znamená, že záznam, na který odkazuje, je nejen průchozí, ale také aktualizovatelný. Změny se okamžitě zachovají v databázi a projeví se v Sadě výsledků objekt v reálném čase.
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---------------------------------"+ "------------------------------------"); } }
Aktualizovatelná Sada výsledků je zvláště užitečné, když chceme aktualizovat určité hodnoty po provedení nějakého srovnání procházením tam a zpět načtenými záznamy. Proces vytváření je podobný předchozímu programu, ale ResultSet zde použité konstanty jsou TYPE_SCROLL_SENSITIVE a CONCUR_UPDATABLE .
Závěr
Na rozdíl od výchozího chování ResultSet umožňuje objektu mít větší flexibilitu. Tato funkce může být aplikací využita nejen k procházení záznamů, ale také k jejich aktualizaci, aby mohly poskytovat lepší služby. Ačkoli standardní chování sady výsledků se zdá být ve srovnání s posuvnou Sada výsledků značně neefektivní , má své vlastní použití, a proto je nenahraditelný.