Zarządzanie bieżącą linią

Napisaliśmy pierwszy program i zadziałał idealnie. Napisaliśmy zapytanie, wykonaliśmy je iw rezultacie metoda executeQuery() zwróciła nam obiektzestaw wynikówAn, który zawiera wszystkie wyniki zapytania. A teraz spróbujemy dowiedzieć się, jak uzyskać z niego te wyniki.

Wynik zapytania może zawierać tysiące wierszy i setki kolumn różnego typu, więc nie jest to tak trywialne zadanie, jak mogłoby się wydawać. Na przykład obrazy mogą być przechowywane w bazie danych, a następnie można uzyskać obraz jako zestaw bajtów lub strumień wejściowy, aby go pobrać.

Ale zaczniemy od najprostszego - od koncepcji „ bieżącej linii wyników ”. Ponieważ wynik ma zwykle wiele wierszy, obiektzestaw wynikówma wskaźnik do bieżącej linii wewnątrz. I sekwencyjnie przełącza wiersze, aby je odczytać za pomocą metody next() .

Takie podejście ma na celu przede wszystkim optymalizację. Sterownik JDBC może nie ładować łańcuchów z bazy danych, dopóki nie zaczniesz ich sekwencyjnie czytać. Ty również przeczytaj FileInputStream sekwencyjnie od początku do końca. Więc to podejście powinno być Ci znane i zrozumiałe.

Jeśli jednak naprawdę tego potrzebujesz, pliki można odczytywać w dowolnym miejscu za pomocą klasy RandomAccessFile .

Klasa ResultSet pozwala również na coś podobnego i umożliwia przesunięcie bieżącego wiersza wzdłuż wyniku w dowolne miejsce. Aby to zrobić, ma następujące metody:

metoda Opis
1 Następny() Przejdź do następnej linii
2 poprzedni() Przełącz do poprzedniej linii
3 jest pierwszy() Bieżąca linia pierwsza?
4 isBeforeFirst() Czy jesteśmy przed pierwszą linią?
5 jestOstatni() Czy obecna linia jest ostatnią?
6 jest po ostatnim() Czy jesteśmy po terminie?
7 bezwzględny(int n) Sprawia, że ​​linia N jest aktualna
8 względny(int n) Przesuwa bieżącą linię o N pozycji do przodu. N może być <0
9 getRow() Zwraca numer linii

Metody są dość proste, ale należy dokonać dwóch wyjaśnień. Wyniki są jakby otoczone pustymi liniami po obu stronach. Dlatego początkowo bieżąca linia znajduje się przed pierwszą linią wyniku. Aby uzyskać pierwszy wiersz, musisz przynajmniej raz wywołać metodę next() .

Jeśli wywołałeś metodę next() w ostatnim wierszu , to przeniosłeś się do wiersza po ostatnim . Nie można z niego odczytać danych, ale nie wystąpi żaden błąd. W tym przypadku metoda isAfterLast() jako wynik zadeklaruje wartość true.

Przykład:

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

Pobieranie danych z bieżącego wiersza

Nauczyłeś się po mistrzowsku zarządzać bieżącą linią. Teraz zastanówmy się, jak uzyskać z niego dane. Do tego obiektzestaw wynikówistnieją specjalne metody, które można opisać za pomocą jednego szablonu:

getType(numberColumns)

Jeśli jednak kolumna ma nazwę, możesz również uzyskać nazwę kolumny:

getType(nameColumns)

Przykład:

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

Poniżej przedstawię tabelę, która pomoże Ci powiązać typy danych SQL i metody ResultSet:

Typ danych SQL getXXX() Metody
ZWĘGLAĆ pobierzString()
VARCHAR pobierzString()
INT getInt()
PLATFORMA getDouble()
KLOB getClob()
KROPELKA getBlob()
DATA pobierzDate()
CZAS uzyskać czas()
ZNAK CZASU pobierz znacznik czasu()

Sedno, myślę, że to rozumiesz.

Pobieranie różnych danych o ResultSet

Wymyśliliśmy, jak odczytywać dane z bieżącej linii: zarówno według numeru kolumny, jak i jej nazwy. Nawiasem mówiąc, jak mogę znaleźć nazwę kolumny według jej numeru? Lub liczba kolumn w wyniku?

Z jednej strony, jeśli piszesz prośbę, wydaje się, że musisz to wszystko wiedzieć. Z drugiej strony możemy napisać program, który wyświetli wynik zapytania na ekranie: zapytanie jest przekazywane do nas i po prostu chcemy wyświetlić na ekranie (w konsoli, stronie internetowej) wszystko, co zwrócił serwer SQL do nas.

JDBC ma do tego specjalny obiekt, interfejs ResultSetMetaData . Uzyskanie obiektu tego typu jest dość proste:

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

Interfejs ResultSetMetaData ma kilka bardzo interesujących metod. Poniżej znajdują się te najpopularniejsze:

1 pobierzLiczbęKolumn() Zwraca liczbę kolumn wynikowych
2 getColumnName(int kolumna) Zwraca nazwę kolumny
3 getColumnLabel(int kolumna) Zwraca opis kolumny
4 getColumnType() Zwraca typ kolumny: liczba (kod specjalny)
5 getColumnTypeName() Zwraca typ kolumny: string
6 getColumnClassName() Zwraca nazwę klasy Java dla typu kolumny
7 getTableName() Zwraca nazwę tabeli
8 getCatalogName() Zwraca nazwę katalogu kolumny
9 getSchemaName() Zwraca nazwę schematu bazy danych
10 isAutoIncrement(int kolumna) Czy kolumna obsługuje AUTO INCREMENT?
jedenaście isNullable() Czy kolumna może zawierać NULL?

Wykorzystajmy to, aby dowiedzieć się trochę o naszym stole:

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

Ważny! Zwróć uwagę, że kolumny są numerowane od 1. Nawiasem mówiąc, wiersze też. Jakie to niezwykłe, prawda?

A oto wynik jaki uzyskałem po uruchomieniu programu:

„C:\Program Files\Java\jdk-17.0.3.1\bin\java.exe...
ID java.lang.Integer INT 4
nazwa java.lang.string VARCHAR 12
poziom java.lang.Integer INT 4
stworz Date java.sql.data DATA 91
Proces zakończony kodem wyjścia 0