Αυτό το σεμινάριο εξηγεί πώς να χρησιμοποιείτε το JDBC ResultSet για την ανάκτηση δεδομένων. Θα μάθουμε επίσης για τις διεπαφές ResultSetMetaData και DatabaseMetaData με παραδείγματα:
Στο JDBC DriverManager σεμινάριο του Σειρά σεμιναρίων JDBC , μάθαμε πώς να χρησιμοποιούμε τον JDBC DriverManager και τις μεθόδους του, JDBC PreparedStatement σε εφαρμογές Java.
Σε αυτό το σεμινάριο, θα συζητήσουμε τις υπόλοιπες διεπαφές της JDBC. Έχουμε καλύψει τις διεπαφές Statement, PreparedStatement και CallableStatement σε προηγούμενα σεμινάρια.
Εδώ, θα μάθουμε για τις διεπαφές JDBC ResultSet, ResultSetMetaData και DatabaseMetaData, τις μεθόδους τους και πώς να χρησιμοποιούμε τις μεθόδους σε πρόγραμμα Java.
Διεπαφή JDBC ResultSet
Η διεπαφή ResultSet υπάρχει στο πακέτο java.sql. Χρησιμοποιείται για την αποθήκευση των δεδομένων που επιστρέφονται από τον πίνακα της βάσης δεδομένων μετά την εκτέλεση των εντολών SQL στο πρόγραμμα Java. Το αντικείμενο ResultSet διατηρεί το σημείο του δρομέα στα δεδομένα του αποτελέσματος. Εξ ορισμού, ο δρομέας τοποθετείται πριν από την πρώτη γραμμή των δεδομένων του αποτελέσματος.
Η μέθοδος next() χρησιμοποιείται για τη μετακίνηση του δρομέα στην επόμενη θέση με κατεύθυνση προς τα εμπρός. Θα επιστρέψει FALSE αν δεν υπάρχουν άλλες εγγραφές. Ανακτά δεδομένα καλώντας τη μέθοδο executeQuery() χρησιμοποιώντας οποιοδήποτε από τα αντικείμενα statement. Μπορεί να είναι αντικείμενο Statement ή PreparedStatement ή CallableStatement. Οι διεπαφές PreparedStatement, και CallableStatement είναι οι υπο-διεπαφές της Statementδιεπαφή.
Διεπαφή δήλωσης
Statement statemnt1 = conn.createStatement(); ResultSet rs1 = statemnt1.executeQuery("Select * from EMPLOYEE_DETAILS"),
Διεπαφή PreparedStatement
PreparedStatement pstatemnt1 = conn.prepareStatement(insert_query); ResultSet rs1 = pstatemnt1.executeQuery("Select * from EMPLOYEE_DETAILS"),
Μπορούμε να χρησιμοποιήσουμε τη μέθοδο getX() για να λάβουμε τα δεδομένα των στηλών κατά την επανάληψη των αποτελεσμάτων, όπου X - είναι ο τύπος δεδομένων της στήλης. Μπορούμε να χρησιμοποιήσουμε είτε τα ονόματα των στηλών είτε τον δείκτη για να λάβουμε τις τιμές χρησιμοποιώντας τις μεθόδους getX().
while(rs1.next()) { int empNum = rs1.getInt("empNum"), String lastName = rs1.getString("lastName"), String firstName = rs1.getString("firstName"), String email = rs1.getString("email"), String deptNum = rs1.getString("deptNum"), String salary = rs1.getString("salary"), System.out.println(empNum + "," +lastName+ "," +firstName+ "," +email +", "+deptNum +"," +salary); }
Μπορούμε επίσης να αναφέρουμε τον αριθμό δείκτη της Στήλης αντί για το Όνομα Στήλης στις μεθόδους getX().
while(rs1.next()) { int empNum = rs1.getInt(1), String lastName = rs1.getString(2), String firstName = rs1.getString(3), String email = rs1.getString(4), String deptNum = rs1.getString(5), String salary = rs1.getString(6), System.out.println(empNum + "," +lastName+ "," +firstName+ "," +email +", "+deptNum +"," +salary); }
Τύποι ResultSet
Από προεπιλογή, μπορούμε να επαναλαμβάνουμε τα δεδομένα/τιμές στο ResultSet που έχουν επιστραφεί ως έξοδος της εκτελεσμένης εντολής SQL προς τα εμπρός. Μπορούμε να επαναλαμβάνουμε τις τιμές προς άλλες κατευθύνσεις χρησιμοποιώντας το Scrollable ResultSet. Μπορούμε να καθορίσουμε τον τύπο και την ταυτόχρονη χρήση του ResultSet κατά τη δημιουργία των αντικειμένων Statement, PreparedStatement και CallableStatement.
Υπάρχουν 3 τύποι στο ResultSet:
- TYPE_FORWARD_ONLY: Είναι η προεπιλεγμένη επιλογή, όπου ο δρομέας κινείται από την αρχή προς το τέλος, δηλαδή προς τα εμπρός.
- TYPE_SCROLL_INSENSITIVE: Σε αυτόν τον τύπο, θα κάνει τον δρομέα να κινείται τόσο προς τα εμπρός όσο και προς τα πίσω. Εάν κάνουμε οποιαδήποτε αλλαγή στα δεδομένα κατά την επανάληψη των αποθηκευμένων δεδομένων, δεν θα ενημερώνεται στο σύνολο δεδομένων εάν κάποιος αλλάξει τα δεδομένα στη ΒΔ. Επειδή το σύνολο δεδομένων έχει τα δεδομένα από τη στιγμή που το ερώτημα SQL επιστρέφει τα δεδομένα.
- TYPE_SCROLL_SENSITIVE: Είναι παρόμοιο με το TYPE_SCROLL_INSENSITIVE, με τη διαφορά ότι αν κάποιος ενημερώσει τα δεδομένα μετά την επιστροφή των δεδομένων από το ερώτημα SQL, κατά την επανάληψη θα αντικατοπτρίζει τις αλλαγές στο σύνολο δεδομένων.
Συγχρονισμός ResultSet
Υπάρχουν 2 τρόποι συγχρονισμού στο ResultSet:
- ResultSet.CONCUR_READ_ONLY: Είναι η προεπιλεγμένη κατάσταση ταυτόχρονης λειτουργίας. Μπορούμε μόνο να διαβάσουμε τα δεδομένα στο ResultSet. Η ενημέρωση δεν εφαρμόζεται.
- ResultSet.CONCUR_UPDATABLE: Μπορούμε να ενημερώσουμε τα δεδομένα στο αντικείμενο ResultSet.
Ορισμένες βάσεις δεδομένων δεν υποστηρίζουν τη λειτουργία ταυτόχρονης εκτέλεσης για όλους τους τύπους ResultSet. Σε αυτή την περίπτωση, πρέπει να ελέγξουμε αν υποστηρίζουν τον επιθυμητό τύπο και τη λειτουργία ταυτόχρονης εκτέλεσης χρησιμοποιώντας τη μέθοδο supportsResultSetConcurrency().
Μέθοδοι στη διεπαφή ResultSet
Υπάρχουν 4 κατηγορίες μεθόδων ResultSet:
- Μέθοδοι πλοήγησης
- Μέθοδοι Getter
- Μέθοδοι Setter
- Διάφορες μέθοδοι
Αρχικά, θα συζητήσουμε τις μεθόδους πλοήγησης και στη συνέχεια θα προχωρήσουμε περαιτέρω.
#1) Μέθοδοι πλοήγησης
Αυτή η μέθοδος χρησιμοποιείται για τη μετακίνηση του δρομέα στο σύνολο δεδομένων.
- Boolean absolute(int row): Χρησιμοποιείται για τη μετακίνηση του δρομέα στην καθορισμένη γραμμή που αναφέρεται στην παράμετρο και επιστρέφει true αν η λειτουργία είναι επιτυχής, διαφορετικά επιστρέφει false.
- Void afterLast(): Κάνει τον κέρσορα του ResultSet να μετακινηθεί μετά την τελευταία γραμμή.
- Void beforeFirst(): Κάνει τον κέρσορα του ResultSet να μετακινηθεί πριν από την πρώτη γραμμή.
- Boolean first(): Κάνει το δρομέα του ResultSet να μετακινηθεί στην πρώτη γραμμή. Επιστρέφει True αν η λειτουργία είναι επιτυχής αλλιώς False.
- Boolean last(): Κάνει το δρομέα του ResultSet να μετακινηθεί στην τελευταία γραμμή. Επιστρέφει True αν η λειτουργία είναι επιτυχής αλλιώς False.
- Boolean next(): Κάνει τον δρομέα ResultSet να μετακινηθεί στην επόμενη γραμμή. Επιστρέφει True αν υπάρχουν περισσότερες εγγραφές και False αν δεν υπάρχουν άλλες εγγραφές.
- Boolean previous(): Κάνει τον κέρσορα του ResultSet να μετακινηθεί στην προηγούμενη γραμμή. Επιστρέφει True αν η λειτουργία είναι επιτυχής, διαφορετικά False.
- Boolean relative(): Μετακινεί το δρομέα στο δεδομένο αριθμό γραμμών είτε προς τα εμπρός είτε προς τα πίσω.
- Int getRow(): Επιστρέφει τον τρέχοντα αριθμό γραμμής στον οποίο δείχνει τώρα το αντικείμενο ResultSet.
- Void moveToCurrentRow(): Μετακινεί τον κέρσορα πίσω στην τρέχουσα γραμμή, εάν βρίσκεται στη γραμμή εισαγωγής.
- Void moveToInsertRow(): Μετακινεί το δρομέα στη συγκεκριμένη γραμμή για να εισαγάγει τη γραμμή στη Βάση Δεδομένων. Θυμάται την τρέχουσα θέση του δρομέα. Έτσι μπορούμε να χρησιμοποιήσουμε τη μέθοδο moveToCurrentRow() για να μετακινήσουμε το δρομέα στην τρέχουσα γραμμή μετά την εισαγωγή.
Σε αυτό το σεμινάριο, όλα τα προγράμματα είναι γραμμένα σε Java. Έχουμε χρησιμοποιήσει την έκδοση Java 8 και τη ΒΔ Oracle.
Μπορείτε να κατεβάσετε το λογισμικό Oracle από εδώ
Μπορείτε να κατεβάσετε την έκδοση 8 της Java από εδώ
Διαθέτει τη διαδικασία εγκατάστασης της Java βήμα προς βήμα.
Πρόγραμμα παραδείγματος JDBC ResultSet: (Χρήση μεθόδων πλοήγησης)
package com.STH.JDBC; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class ResultSet_Example { public static void main(String[] args) throws ClassNotFoundException { // TODO Αυτόματα παραγόμενο στέλεχος μεθόδου //Επιλογή ερωτήματος String select_query = "select * fromemployee_details"; Class.forName("oracle.jdbc.driver.OracleDriver"); //Σύνδεση με Oracle DB try(Connection conn = DriverManager.getConnection("jdbc:oracle:thin:system/pass123@localhost:1521:X E")) { //Δημιουργία αντικειμένου DatabaseMetaData DatabaseMetaData dbmd = conn.getMetaData(); //Έλεγχος αν ο οδηγός υποστηρίζει scroll sensitive type και concur updatable boolean isSupportResultSetType =dbmd.supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); if(isSupportResultSetType == true) { // Δημιουργία προετοιμασμένης δήλωσης PreparedStatement pstatemnt1 = conn.prepareStatement(select_query,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet. CONCUR_UPDATABLE); ResultSet rs = pstatemnt1.executeQuery(); //Μετακίνηση του δρομέα στο σημείο της πρώτης γραμμής rs.first(),System.out.println("ΠΡΩΤΗ ΣΕΙΡΑ \n EMP NUM = " + rs.getInt("empNum") + "\n LAST NAME = "+ rs.getString(2)+"\n FIRST NAME = " + rs.getString(3)); //Μετακινούμε τον κέρσορα στο σημείο της τελευταίας σειράς rs.last(); System.out.println("ΤΕΛΕΥΤΑΙΑ ΣΕΙΡΑ \n EMP NUM = " + rs.getInt("empNum") + "\n LAST NAME = "+ rs.getString(2)+"\n FIRST NAME = " + rs.getString(3)); //Μετακινούμε τον κέρσορα στο σημείο πριν από την πρώτη σειρά rs.beforeFirst(),System.out.println("Ο δρομέας δείχνει πριν από την πρώτη σειρά. Χρησιμοποιήστε την next() για να μετακινηθείτε προς τα εμπρός"); //Μετακίνηση του δρομέα στο σημείο της πρώτης σειράς χρησιμοποιώντας την next() rs.next(); System.out.println("ΠΡΩΤΗ ΣΕΙΡΑ \n EMP NUM = " + rs.getInt("empNum") + "\n LAST NAME = "+ rs.getString(2)+"\n FIRST NAME = " + rs.getString(3)); //Μετακίνηση του δρομέα στο σημείο μετά την τελευταία σειρά rs.afterLast(); System.out.println("Cursorδείχνει μετά την τελευταία σειρά. Χρησιμοποιήστε την προηγούμενη() για να μετακινηθείτε προς τα πίσω"); //Μετακινώντας τον κέρσορα στο σημείο της τελευταίας σειράς χρησιμοποιώντας την προηγούμενη() rs.previous(); System.out.println("LAST ROW \n EMP NUM = " + rs.getInt("empNum") + "\n LAST NAME = "+ rs.getString(2)+"\n FIRST NAME = " + rs.getString(3)); //Μετακινώντας τον κέρσορα στο σημείο της τρίτης σειράς rs.absolute(3); System.out.println("Ο κέρσορας δείχνει στην 3η γραμμή.row"); System.out.println("THIRD ROW \n EMP NUM = " + rs.getInt("empNum") + "\n LAST NAME = "+ rs.getString(2)+"\n FIRST NAME = " + rs.getString(3)); //Moving the cursor to point previous row of third row rs.relative(-1); System.out.println("Cursor is pointing to the 1 row previous to the 3rd row"); System.out.println("Second ROW \n EMP NUM = " + rs.getInt("empNum") + "\n LAST NAME = "+rs.getString(2)+"\n ΠΡΩΤΟ ΟΝΟΜΑ = " + rs.getString(3)); //Μετακίνηση του δρομέα στο σημείο της 4ης γραμμής μετά τη 2η γραμμή rs.relative(4); System.out.println("Ο δρομέας δείχνει στην 4η γραμμή μετά τη 2η γραμμή"); System.out.println("ΕΞΗΜΗ ΣΕΙΡΑ \n ΑΡΙΘΜΟΣ ΕΡΓΑΣΙΑΣ = " + rs.getInt("empNum") + "\n ΟΝΟΜΑΤΕΠΩΝΥΜΟ = "+ rs.getString(2)+"\n ΠΡΩΤΟ ΟΝΟΜΑ = " + rs.getString(3)); //Μετακίνηση του δρομέα στο σημείο της τρέχουσας γραμμήςSystem.out.println(" Current Row = " + rs.getRow()); } } } catch (SQLException e) { e.printStackTrace(); } } }
ΕΞΟΔΟΣ:
Δεδομένα στον πίνακα Employee_details
Επεξήγηση:
Στο παραπάνω πρόγραμμα έχουμε υλοποιήσει τις μεθόδους first(), last(), beforeFirst(), afterLast(), next(), previous(), absolute(), relative() και getRow() στο ResultSet. Για να χρησιμοποιήσουμε αυτές τις μεθόδους ορίζουμε τις τιμές ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE στη μέθοδο prepareStatement.
Στη συνέχεια, θα συζητήσουμε ποιες είναι οι Μέθοδοι Getter στο ResultSet:
#2) Μέθοδοι Getter
Το ResultSet έχει αποθηκεύσει τα δεδομένα του πίνακα από τη Βάση Δεδομένων. Οι μέθοδοι Getter χρησιμοποιούνται για να πάρουμε τις τιμές του πίνακα στο ResultSet. Για αυτό, πρέπει να περάσουμε είτε την τιμή του δείκτη της στήλης είτε το όνομα της στήλης.
Ακολουθούν οι μέθοδοι getter στο ResultSet:
- int getInt(int ColumnIndex): Χρησιμοποιείται για να λάβετε την τιμή της καθορισμένης στήλης Index ως τύπο δεδομένων int.
- float getFloat(int ColumnIndex): Χρησιμοποιείται για τη λήψη της τιμής της καθορισμένης στήλης Index ως τύπος δεδομένων float.
- java.sql.date getDate(int ColumnIndex): Χρησιμοποιείται για να λάβετε την τιμή της καθορισμένης στήλης Index ως τιμή ημερομηνίας.
- int getInt(String ColumnName): Χρησιμοποιείται για να λάβετε την τιμή της καθορισμένης στήλης ως τύπο δεδομένων int.
- float getFloat(String ColumnName): Χρησιμοποιείται για να λάβετε την τιμή της καθορισμένης στήλης ως τύπο δεδομένων float.
- Java.sql.date getDate(String ColumnName): Χρησιμοποιείται για να λάβετε την τιμή της καθορισμένης στήλης ως τιμή ημερομηνίας.
Στη διεπαφή ResultSet υπάρχουν μέθοδοι getter για όλους τους πρωτόγονους τύπους δεδομένων (Boolean, long, double) και String επίσης. Μπορούμε να λάβουμε έναν πίνακα και δυαδικό τύπο δεδομένων επίσης από τη βάση δεδομένων. Διαθέτει επίσης μεθόδους για αυτό.
#3) Μέθοδοι Setter/Updater
Μπορούμε να ενημερώσουμε την τιμή στη Βάση Δεδομένων χρησιμοποιώντας τις μεθόδους ResultSet Updater. Είναι παρόμοιες με τις μεθόδους Getter, αλλά εδώ πρέπει να περάσουμε τις τιμές/δεδομένα για τη συγκεκριμένη στήλη που θέλουμε να ενημερώσουμε στη Βάση Δεδομένων.
Ακολουθούν οι μέθοδοι ενημέρωσης στο ResultSet:
- void updateInt(int ColumnIndex, int Value): Χρησιμοποιείται για την ενημέρωση της τιμής της καθορισμένης στήλης Index με μια τιμή int.
- void updateFloat(int ColumnIndex, float f): Χρησιμοποιείται για την ενημέρωση της τιμής της καθορισμένης στήλης Index με την τιμή float.
- void updateDate(int ColumnIndex, Date d): Χρησιμοποιείται για την ενημέρωση της τιμής της καθορισμένης στήλης Index με την τιμή της ημερομηνίας.
- void updateInt(String ColumnName, int Value): Χρησιμοποιείται για την ενημέρωση της τιμής της καθορισμένης στήλης με τη δεδομένη τιμή int.
- void updateFloat(String ColumnName, float f): Χρησιμοποιείται για την ενημέρωση της τιμής της καθορισμένης στήλης με τη δεδομένη τιμή float.
- Java.sql.date getDate(String ColumnName): Χρησιμοποιείται για την ενημέρωση της τιμής της καθορισμένης στήλης με τη δεδομένη τιμή ημερομηνίας.
Υπάρχουν μέθοδοι Updater για όλους τους πρωτόγονους τύπους δεδομένων (Boolean, long, double) και String επίσης στη διεπαφή ResultSet.
Οι μέθοδοι Updater απλώς ενημερώνουν τα δεδομένα στο αντικείμενο ResultSet. Οι τιμές θα ενημερωθούν στη ΒΔ μετά την κλήση της μεθόδου insertRow ή updateRow.
Ενημέρωση γραμμής:
Μπορούμε να ενημερώσουμε τα δεδομένα σε μια γραμμή καλώντας τις μεθόδους updateX(), περνώντας το όνομα ή τον δείκτη της στήλης και τις τιμές που θέλουμε να ενημερώσουμε. Μπορούμε να χρησιμοποιήσουμε οποιονδήποτε τύπο δεδομένων στη θέση του X στη μέθοδο updateX. Μέχρι τώρα, έχουμε ενημερώσει τα δεδομένα στο αντικείμενο ResultSet. Για να ενημερώσουμε τα δεδομένα στη ΒΔ, πρέπει να καλέσουμε τη μέθοδο updateRow().
Εισαγωγή γραμμής:
Πρέπει να χρησιμοποιήσουμε την moveToInsertRow() για να μετακινήσουμε τον κέρσορα για να εισάγουμε μια νέα γραμμή. Το έχουμε ήδη καλύψει αυτό στην ενότητα Μέθοδοι πλοήγησης. Στη συνέχεια, πρέπει να καλέσουμε τη μέθοδο updateX() για να προσθέσουμε τα δεδομένα στη γραμμή. Θα πρέπει να παρέχουμε δεδομένα για όλες τις στήλες, διαφορετικά θα χρησιμοποιηθεί η προεπιλεγμένη τιμή της συγκεκριμένης στήλης.
Μετά την ενημέρωση των δεδομένων, πρέπει να καλέσουμε τη μέθοδο insertRow(). Στη συνέχεια, χρησιμοποιήστε τη μέθοδο moveToCurrentRow(), για να μεταφέρετε τη θέση του δρομέα πίσω στη γραμμή που βρισκόμασταν πριν ξεκινήσουμε την εισαγωγή μιας νέας γραμμής.
Παράδειγμα ResultSet:
package com.STH.JDBC- import java.sql.Connection- import java.sql.DatabaseMetaData- import java.sql.DriverManager- import java.sql.PreparedStatement- import java.sql.ResultSet- import java.sql.SQLException- import java.sql.Statement- public class ResultSet_Example1 { public static void main(String[] args) throws ClassNotFoundException { // TODO Αυτόματα παραγόμενο στέλεχος μεθόδου String select_query ="select empnum,lastName,firstName from employee_details"; String insert_query = "insert into employee_details values(?,?,?,?,?,?,?,?)"; Class.forName("oracle.jdbc.driver.OracleDriver"); //Σύνδεση με Oracle DB try(Connection conn = DriverManager.getConnection("jdbc:oracle:thin:system/pass123@localhost:1521:XE")) { //Δημιουργία αντικειμένου DatabaseMetaData DatabaseMetaData dbmd = conn.getMetaData(),//Ελέγχουμε αν ο οδηγός υποστηρίζει scroll insensitive type και concur updatable boolean isSupportResultSetType = dbmd.supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); if(isSupportResultSetType == true) { // Δημιουργία προετοιμασμένης δήλωσης PreparedStatement pstatemnt1 =conn.prepareStatement(select_query,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE); ResultSet rs = pstatemnt1.executeQuery(select_query); //Μετακίνηση του δρομέα στο σημείο της τελευταίας γραμμής του πίνακα rs.last(); System.out.println("LAST ROW: Before inserting new Employee"); System.out.println("LAST ROW: EMPNUM = " + rs.getInt(1)); System.out.println("\n EMP NUM = " + rs.getInt("empNum") + "\nLAST NAME = " + rs.getString(2)+"\n FIRST NAME = " + rs.getString(3)); //Ορισμός των τιμών για εισαγωγή στον πίνακα EMPLOYEE_DETAILS //Μετακίνηση του κέρσορα στο σημείο εισαγωγής μιας γραμμής στον πίνακα rs.moveToInsertRow(); //Ενημέρωση της τιμής EMPNUM rs.updateInt(1, 1017); //Ενημέρωση της τιμής LAST NAME rs.updateString(2, "Bond"); //Ενημέρωση της τιμής FIRST NAME rs.updateString(3, "James"); //Εισαγωγή νέας γραμμής rs.insertRow(),// Μετακίνηση του δρομέα στο σημείο της 5ης γραμμής rs.absolute(5); System.out.println("Πριν από την ενημέρωση του EMPNUM της 5ης ΣΕΙΡΑΣ"); System.out.println("\n EMP NUM = " + rs.getInt("empNum") + "\n LAST NAME = "+ rs.getString(2)+"\n FIRST NAME = " + rs.getString(3)); System.out.println(" Ενημέρωση του EMP id του 5ου EMPLOYEE"); //Ανανέωση του EMPNUM της 5ης γραμμής rs.updateInt(1,3005); rs.updateRow(); System.out.println("\n EMPNUM = " + rs.getInt("empNum") + "\n LAST NAME = "+ rs.getString(2)+"\n FIRST NAME = " + rs.getString(3)); //Moving the cursor to point last row rs.last(); System.out.println("LAST ROW: EMPNUM = " + rs.getInt(1)); System.out.println("\n EMP NUM = " + rs.getInt("empNum") + "\n LAST NAME = "+ rs.getString(2)+"\n FIRST NAME = " + rs.getString(3)); } } catch (SQLException e) { e.printStackTrace(); } }}
ΕΞΟΔΟΣ:
Επεξήγηση:
Στο παραπάνω πρόγραμμα αυτό που κάναμε είναι ότι πρώτα, αποθηκεύσαμε τα δεδομένα του πίνακα Employee_details στο αντικείμενο ResultSet χρησιμοποιώντας το ερώτημα SELECT. Στη συνέχεια, εμφανίσαμε τα δεδομένα της τελευταίας γραμμής του πίνακα employee_details χρησιμοποιώντας τη μέθοδο last() του ResultSet. Η μέθοδος moveToInsertRow() κάνει τον κέρσορα να δείχνει την τρέχουσα γραμμή, τώρα η τρέχουσα γραμμή είναι η τελευταία γραμμή.
Οι μέθοδοι updateXXX() χρησιμοποιήθηκαν για την ενημέρωση των τιμών στη γραμμή και η μέθοδος insertRow() εισήγαγε τα δεδομένα σε μια νέα γραμμή. Χρησιμοποιώντας τη μέθοδο absolute(), κάναμε τον δρομέα να δείχνει στην 5η γραμμή. Η μέθοδος UpdateInt() χρησιμοποιήθηκε για την ενημέρωση του EMPNUM με ένα νέο id του 5ου υπαλλήλου στον πίνακα. Μετά από αυτό, εμφανίστηκαν τα δεδομένα για να ελέγξουμε αν το EMPNUM έχει ενημερωθεί ή όχι.
Κατέστησε τον δρομέα να δείχνει την τελευταία γραμμή του πίνακα χρησιμοποιώντας την last() και τον εμφάνισε. Για να εκτελέσουμε την παραπάνω λογική, πρέπει να ορίσουμε τις τιμές ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE στη μέθοδο prepareStatement.
#4) Διάφορες μέθοδοι
- void close(): Χρησιμοποιείται για να κλείσει την περίπτωση ResultSet και να απελευθερώσει τους πόρους που σχετίζονται με την περίπτωση ResultSet.
- ResultSetMetaData getMetaData(): Επιστρέφει το ResultSetMetaData Instance. Έχει τις πληροφορίες σχετικά με τον τύπο και την ιδιότητα των στηλών της εξόδου του ερωτήματος. Θα μάθουμε περισσότερα για το ResultSetMetaData στην επόμενη ενότητα.
ResultSetMetaData
Τι είναι τα μεταδεδομένα;
Μεταδεδομένα σημαίνει δεδομένα σχετικά με τα δεδομένα. Χρησιμοποιώντας αυτή τη διεπαφή, θα λάβουμε περισσότερες πληροφορίες σχετικά με το ResultSet. Είναι διαθέσιμο στο πακέτο java.sql. Κάθε αντικείμενο ResultSet συνδέεται με ένα αντικείμενο ResultSetMetaData.
Αυτό το αντικείμενο θα έχει τις λεπτομέρειες των ιδιοτήτων των στηλών, όπως ο τύπος δεδομένων της στήλης, το όνομα της στήλης, ο αριθμός των στηλών, το όνομα του πίνακα, το όνομα του σχήματος κ.λπ., Μπορούμε να λάβουμε το αντικείμενο ResultSetMetaData χρησιμοποιώντας τη μέθοδο getMetaData() του ResultSet.
Σύνταξη του ResultSetMetaData:
PreparedStatement pstatemnt1 = conn.prepareStatement(insert_query); ResultSet rs1 = pstatemnt1.executeQuery("Select * from EMPLOYEE_DETAILS"); ResultSetMetaData rsmd = rs.getMetaData(),
Σημαντικές μέθοδοι της διεπαφής ResultSetMetaData:
Όνομα μεθόδου | Περιγραφή |
---|---|
String getColumnName(int column) | Επιστρέφει το όνομα της συγκεκριμένης στήλης |
String getColumnTypeName(int column) | Επιστρέφει τον τύπο δεδομένων της συγκεκριμένης στήλης που έχουμε περάσει ως παράμετρο |
String getTableName(int column) | Επιστρέφει το όνομα του πίνακα της στήλης |
String getSchemaName(int column) | Επιστρέφει το όνομα του σχήματος του πίνακα της στήλης |
int getColumnCount() | Επιστρέφει τον αριθμό των στηλών του ResultSet |
boolean isAutoIncrement(int Column) | Επιστρέφει true αν η δεδομένη στήλη είναι Auto Increment, αλλιώς false |
boolean isCaseSensitive(int Column) | Επιστρέφει true αν η δεδομένη στήλη είναι Case Sensitive, αλλιώς false |
Παράδειγμα ResultSetMetaData
package com.STH.JDBC; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; public class ResultSetMetaData_Example { public static void main(String[] args) throws ClassNotFoundException, SQLException { // TODO Αυτόματη δημιουργία stub μεθόδου String QUERY= " select * fromemployee_details"; Class.forName("oracle.jdbc.driver.OracleDriver"); try(Connection conn = DriverManager.getConnection("jdbc:oracle:thin:system/pass123@localhost:1521:XE")) { Statement statemnt1 = conn.createStatement(); ResultSet rs1 =null; rs1 = statemnt1.executeQuery(QUERY); ResultSetMetaData rsmd = rs1.getMetaData(); System.out.println(" Χρησιμοποιούμε ResultSetMetaData "),System.out.println("No: of Columns: " + rsmd.getColumnCount())- System.out.println("ColumnName of Column 1: " + rsmd.getColumnName(1))- System.out.println("Data Type of Column 2: " + rsmd.getColumnTypeName(2))- System.out.println("Table Name of the Column 1: " + rsmd.getTableName(1))- System.out.println("Schema Name of the Column 1: " + rsmd.getSchemaName(1))} }
ΕΞΟΔΟΣ:
Επεξήγηση:
Στο παραπάνω πρόγραμμα, έχουμε υλοποιήσει τις μεθόδους getColumnCount(),getColumnName(), getColumnTypeName(), getTableName() και getSchemaName() στη διεπαφή ResultSetMetaData.
DatabaseMetaData
Η διασύνδεση DatabaseMetaData παρέχει πληροφορίες σχετικά με τη βάση δεδομένων, όπως το DatabaseName, η έκδοση της βάσης δεδομένων και ούτω καθεξής.
Σημαντικές μέθοδοι της διεπαφής DatabaseMetaData:
Όνομα μεθόδου | Περιγραφή |
---|---|
String getDriverName() | Θα επιστρέψει το όνομα του προγράμματος οδήγησης JDBC που χρησιμοποιούμε στο πρόγραμμα Java μας |
String getDriverVersion() | Επιστρέφει τον αριθμό έκδοσης του προγράμματος οδήγησης JDBC |
String getUserName() | Επιστρέφει το όνομα χρήστη της βάσης δεδομένων που χρησιμοποιούμε |
String getDatabaseProductName() | Επιστρέφει το όνομα της βάσης δεδομένων που χρησιμοποιούμε |
String getDatabaseProductVersion() | Επιστρέφει τον αριθμό έκδοσης της βάσης δεδομένων που χρησιμοποιούμε |
ResultSet getSchemas() | Επιστρέφει τα ονόματα των σχημάτων που είναι διαθέσιμα στη συνδεδεμένη βάση δεδομένων |
String getStringFunctions() | Επιστρέφει τον κατάλογο των συναρτήσεων συμβολοσειράς που είναι διαθέσιμες στη συνδεδεμένη βάση δεδομένων |
String getTimeDateFunctions() | Επιστρέφει τον κατάλογο των λειτουργιών ώρας και ημερομηνίας που είναι διαθέσιμες στη συνδεδεμένη βάση δεδομένων. |
String getURL() | Επιστρέφει τη διεύθυνση URL για τη βάση δεδομένων |
Boolean isReadOnly() | Επιστρέφει εάν η βάση δεδομένων βρίσκεται σε κατάσταση λειτουργίας μόνο για ανάγνωση. |
Boolean supportsBatchUpdates() | Επιστρέφει εάν η βάση δεδομένων υποστηρίζει ενημερώσεις παρτίδας |
Boolean supportsSavepoints() | Επιστρέφει εάν η βάση δεδομένων υποστηρίζει σημεία αποθήκευσης |
Boolean supportsStatementPooling() | Επιστρέφει εάν η βάση δεδομένων υποστηρίζει τη συγκέντρωση δηλώσεων |
Boolean supportsStoredProcedures() | Επιστρέφει εάν η βάση δεδομένων υποστηρίζει αποθηκευμένες διαδικασίες |
Boolean supportsOuterJoins() | Επιστρέφει εάν η βάση δεδομένων υποστηρίζει Outer Join |
Εδώ, παραθέσαμε μερικές σημαντικές μεθόδους της διεπαφής DatabaseMetaData. Μπορείτε να ανατρέξετε στον επίσημο ιστότοπο του Oracle όπου μπορείτε να δείτε όλες τις μεθόδους που είναι διαθέσιμες στη διεπαφή DatabaseMetaData.
DatabaseMetaData Παράδειγμα:
package com.STH.JDBC- import java.sql.Connection- import java.sql.DatabaseMetaData- import java.sql.DriverManager- import java.sql.ResultSet- import java.sql.ResultSetMetaData- import java.sql.SQLException- import java.sql.Statement- public class DatabaseMetaData_Example { public static void main(String[] args) throws ClassNotFoundException, SQLException { // TODO Αυτόματα παραγόμενη μέθοδος stubClass.forName("oracle.jdbc.driver.OracleDriver"); Connection conn = DriverManager.getConnection("jdbc:oracle:thin:system/pass123@localhost:1521:XE"); DatabaseMetaData dbmd = conn.getMetaData(); System.out.println("Χρήση DatabaseMetaData"); System.out.println("Driver Name: " + dbmd.getDriverName()); System.out.println("Driver Version: "+ dbmd.getDriverVersion())); System.out.println("UserName of theΒάση δεδομένων: " + dbmd.getUserName())- System.out.println("Database Product Name: " + dbmd.getDatabaseProductName())- System.out.println("Database Product Version: " + dbmd.getDatabaseProductVersion())- System.out.println("List of String Functions in the Database: " + dbmd.getStringFunctions())- System.out.println("List of Time & Date functions in the Database: " + dbmd.getTimeDateFunctions()),System.out.println("URL της βάσης δεδομένων: " + dbmd.getURL())- System.out.println("Database is read - only? " +dbmd.isReadOnly())- System.out.println("Support Batch Updates? " + dbmd.supportsBatchUpdates())- System.out.println("Support savepoints? " + dbmd.supportsSavepoints())- System.out.println("Support Statement Pooling?" + dbmd.supportsStatementPooling())- System.out.println("Support StoredProcedures? " + dbmd.supportsStoredProcedures()); System.out.println("Support Outer Join?" + dbmd.supportsOuterJoins()); } }
ΕΞΟΔΟΣ:
Επεξήγηση:
Στο παραπάνω πρόγραμμα, έχουμε χρησιμοποιήσει/υλοποιήσει τις μεθόδους getDriverName(), getDriverVersion(), getUserName(), getDatabaseProductName(), getDatabaseProductVersion(), getStringFunctions(), getTimeDateFunctions(), getURL(), isReadOnly(), supportsBatchUpdates(), supportsStatementPooling(), supportsSavepoints(), supportsStoredProcedures() και supportsOuterJoins() στη διεπαφή DatabaseMetaData.
Σημεία που πρέπει να σημειωθούν:
- Η διεπαφή JDBC ResultSet χρησιμοποιείται για την αποθήκευση των δεδομένων από τη βάση δεδομένων και τη χρήση τους στο πρόγραμμα Java.
- Μπορούμε επίσης να χρησιμοποιήσουμε το ResultSet για να ενημερώσουμε τα δεδομένα χρησιμοποιώντας τις μεθόδους updateXXX().
- Το αντικείμενο ResultSet δείχνει τον κέρσορα πριν από την πρώτη γραμμή των δεδομένων του αποτελέσματος. Χρησιμοποιώντας τη μέθοδο next(), μπορούμε να κάνουμε επανάληψη στο ResultSet.
- Έχουμε μεθόδους πλοήγησης του ResultSet για να κινηθούμε περαιτέρω στο αντικείμενο ResultSet
- Το ResultMetaData χρησιμοποιείται για να λάβετε περισσότερες πληροφορίες σχετικά με το ResultSet, όπως το όνομα της στήλης, τον αριθμό των στηλών, τον τύπο δεδομένων της στήλης κ.λπ.
- Το DatabaseMetData χρησιμοποιείται για να πάρει τις πληροφορίες σχετικά με τη βάση δεδομένων που έχουμε συνδέσει
Συχνές ερωτήσεις
Q #1) Ποια είναι η χρήση του ResultSet;
Απαντήστε: Το ResultSet χρησιμοποιείται για την αποθήκευση και ανάκτηση δεδομένων από τη ΒΔ. Όταν εκτελεστεί η μέθοδος executeQuery(), θα επιστρέψει το αντικείμενο ResultSet. Μπορούμε να χρησιμοποιήσουμε αυτό το αντικείμενο ResultSet στο πρόγραμμά μας για να εκτελέσουμε τη λογική.
Q #2) Πώς να ελέγξετε αν το ResultSet είναι άδειο ή όχι;
Απαντήστε: Δεν υπάρχουν προκαθορισμένες μέθοδοι όπως length(), size() διαθέσιμες για να ελέγξουμε το IsResultSet Empty. Μπορούμε να χρησιμοποιήσουμε τη μέθοδο next() για να επαναλάβουμε και αν επιστρέψει True, τότε δεν είναι άδειο, αν επιστρέψει False σημαίνει ότι το ResultSet είναι άδειο.
Q #3) Είναι δυνατόν το ResultSet να είναι null;
Απαντήστε: Όχι, η μέθοδος executeQuery() επιστρέφει το αντικείμενο ResultSet που δεν μπορεί ποτέ να είναι null.
Q #4) Τι είναι το updatable ResultSet;
Απαντήστε: Ένα updatable ResultSet αντικείμενο χρησιμοποιείται για την ενημέρωση των δεδομένων στη στήλη, την εισαγωγή δεδομένων σε στήλες και τη διαγραφή γραμμών. Για να κάνουμε ένα ResultSet ως updatable, πρέπει να κάνουμε τον τύπο κύλισης ως sensitive ή insensitive και τον τύπο CONCUR ως updatable.
ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE.
Q #5) Πώς να λάβετε το όνομα της βάσης δεδομένων που έχει συνδεθεί;
Απαντήστε: Μπορούμε να χρησιμοποιήσουμε τη μέθοδο getDatabaseProductName() του αντικειμένου DatabaseMetaData.
Συμπέρασμα
Σε αυτό το σεμινάριο, συζητήσαμε ποιες είναι οι διεπαφές ResultSet, ResultSetMetaData και DatabaseMetaData και τις σημαντικές μεθόδους τους που χρησιμοποιούνται συνήθως στα προγράμματα JDBC. Είδαμε επίσης πώς να ενημερώνουμε τα δεδομένα στη ΒΔ χρησιμοποιώντας ResultSet. Τα ResultSetMetadata περιέχουν πληροφορίες σχετικά με το ResultSet, όπως το όνομα στήλης, το πλήθος στηλών και ούτω καθεξής.
Το DatabaseMetaData περιέχει πληροφορίες για τη βάση δεδομένων.
<,