Administrere gjeldende linje

Vi skrev det første programmet og det fungerte perfekt. Vi skrev en spørring, utførte den, og som et resultat returnerte executeQuery() -metoden et objekt til ossresultatsettEn som inneholder alle resultatene av spørringen. Og nå skal vi prøve å finne ut hvordan vi får disse resultatene fra det.

Spørreresultatet kan inneholde tusenvis av rader og hundrevis av kolonner av ulike typer, så dette er ikke en så triviell oppgave som du kanskje tror. For eksempel kan bilder lagres i databasen, så kan du få et bilde som et sett med byte eller en InputStream for å laste det ned.

Men vi starter med det enkleste - med konseptet " gjeldende resultatlinje ". Siden resultatet vanligvis har mange rader, vil objektetresultatsetthar en peker til gjeldende linje inne. Og bytter sekvensielt linjene for å lese dem ved hjelp av next() -metoden .

Denne tilnærmingen er primært gjort for optimalisering. JDBC-driveren laster kanskje ikke inn strenger fra databasen før du sekvensielt får lest dem. Du leser også FileInputStream sekvensielt fra begynnelsen til slutten. Så denne tilnærmingen bør være kjent og forståelig for deg.

Men hvis du virkelig trenger det, kan filer leses hvor som helst ved å bruke RandomAccessFile- klassen .

ResultSet- klassen tillater også noe lignende og lar deg flytte gjeldende rad langs resultatet hvor som helst. For å gjøre dette har den følgende metoder:

Metode Beskrivelse
1 neste() Bytt til neste linje
2 tidligere() Bytt til forrige linje
3 isFirst() Nåværende linje først?
4 isBeforeFirst() Står vi foran første linje?
5 isLast() Er gjeldende linje den siste?
6 erEtterSiste() Er vi etter fristen?
7 absolutt(int n) Gjør den N-te linjen gjeldende
8 relativ(int n) Flytter gjeldende linje N posisjoner fremover. N kan være <0
9 getRow() Returnerer linjenummeret

Metodene er ganske enkle, men to forklaringer må gjøres. Resultatene er så å si innrammet av tomme streker på begge sider. Derfor er den gjeldende linjen i utgangspunktet før den første linjen i resultatet. Og for å få den første raden, må du kalle neste()- metoden minst én gang .

Hvis du kalte neste() -metoden på den siste raden , så flyttet du til linjen etter den siste . Du kan ikke lese data fra den, men det vil ikke oppstå noen feil. Her vil isAfterLast() -metoden erklære sann som resultat.

Eksempel:

Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery("SELECT * FROM user");

System.out.println( results.getRow() );        	// 0
System.out.println( results.isBeforeFirst() );  // true
System.out.println( results.isFirst() );          	// false

results.next();

System.out.println( results.getRow() );        	// 1
System.out.println( results.isBeforeFirst() );  // false
System.out.println( results.isFirst() );          	// true

results.next();

System.out.println( results.getRow() );        	// 2
System.out.println( results.isBeforeFirst() );  // false
System.out.println( results.isFirst() );          	// false

Henter data fra gjeldende rad

Du har lært å mesterlig styre den gjeldende linjen. La oss nå finne ut hvordan du får data fra den. For dette, objektetresultatsettdet er spesielle metoder som alle kan beskrives med én mal:

getType(numberColumns)

Men hvis kolonnen har et navn, kan du også finne kolonnenavnet:

getType(nameColumns)

Eksempel:

while (results.next()) {
        	Integer id = results.getInt(“id”);
        	String name = results.getString(“name”);
        	System.out.println(results.getRow() + ". " + id + "\t"+ name);
}

Nedenfor vil jeg gi en tabell som vil hjelpe deg å knytte SQL-datatyper og ResultSet-metoder:

SQL-datatype getXXX() metoder
CHAR getString()
VARCHAR getString()
INT getInt()
FLYTE getDouble()
CLOB getClob()
BLOB getBlob()
DATO getDate()
TID getTime()
TIDSSTIMPEL getTimestamp()

Poenget, jeg tror du skjønner det.

Få forskjellige data om ResultSet

Vi fant ut hvordan vi skulle lese data fra gjeldende linje: både ved kolonnenummeret og navnet. Hvordan kan jeg forresten finne ut kolonnenavnet etter nummeret? Eller antall kolonner i resultatet?

På den ene siden, hvis du skriver en forespørsel, så ser det ut til at du må vite alt dette. På den annen side kan vi skrive et program som viser resultatet av en spørring på skjermen: spørringen sendes til oss og vi vil bare vise på skjermen (i konsollen, nettsiden) alt som SQL-serveren returnerte til oss.

JDBC har et spesielt objekt for dette, ResultSetMetaData- grensesnittet . Å få et objekt av denne typen er ganske enkelt:

Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery("SELECT * FROM user");
ResultSetMetaData resultSetMetaData = results.getMetaData();

ResultSetMetaData- grensesnittet har noen veldig interessante metoder. Nedenfor er de mest populære:

1 getColumnCount() Returnerer antall resultatkolonner
2 getColumnName(int kolonne) Returnerer kolonnenavnet
3 getColumnLabel(int kolonne) Returnerer beskrivelsen av kolonnen
4 getColumnType() Returnerer kolonnetype: nummer (spesialkode)
5 getColumnTypeName() Returnerer kolonnetype: streng
6 getColumnClassName() Returnerer java-klassenavnet for kolonnetypen
7 getTableName() Returnerer tabellnavnet
8 getCatalogName() Returnerer katalognavnet til kolonnen
9 getSchemaName() Returnerer skjemanavnet til databasen
10 isAutoIncrement(int kolonne) Støtter kolonnen AUTO INKREMENT?
elleve isNullable() Kan en kolonne inneholde NULL?

La oss bruke den til å lære litt om tabellen vår:

ResultSetMetaData metaData = results.getMetaData();
int columnCount = metaData.getColumnCount();
for (int column = 1; column <= columnCount; column++)
{
        	String name = metaData.getColumnName(column);
        	String className = metaData.getColumnClassName(column);
        	String typeName = metaData.getColumnTypeName(column);
        	int type = metaData.getColumnType(column);

        	System.out.println(name + "\t" + className + "\t" + typeName + "\t" + type);
}

Viktig! Vær oppmerksom på at kolonner er nummerert fra 1. Rader også. Hvor uvanlig er det, ikke sant?

Og dette er resultatet jeg fikk etter å ha kjørt programmet:

"C:\Program Files\Java\jdk-17.0.3.1\bin\java.exe...
id java.lang.Integer INT 4
Navn java.lang.string VARCHAR 12
nivå java.lang.Integer INT 4
opprettet dato java.sql.date DATO 91
Prosessen avsluttet med utgangskode 0