Typy danych

Spójrzmy na tabelę:

„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

W trzeciej kolumnie widzimy typy: INT , VARCHAR , DATE . Są to typy serwerów SQL. Serwer oznacza, że ​​podaje dane z tymi typami, o których wie. W jaki sposób te typy są konwertowane na typy Java?

Jest to dokładnie jedna z rzeczy, które zostały ujednolicone w JDBC. Twórcy JDBC zaczęli od poprawienia listy typów SQL. Istnieje specjalna klasa ze stałymi:

class java.sql.Types {
   public static final int CHAR         =   1;
   public static final int NUMERIC    	=   2;
   public static final int DECIMAL     	=   3;
   public static final int INTEGER      =   4;
   public static final int FLOAT        =   6;
   public static final int REAL         =   7;}

Numer nie jest numerem seryjnym w klasie, ale typem identyfikatora na liście typów SQL w specyfikacji SQL. To są liczby, które widziałeś w przykładzie na początku wykładu.

Również w klasie ResultSet znajdują się metody, które mogą konwertować jeden typ danych na inny. Nie wszystkie typy można konwertować na siebie, ale logika jest wystarczająco jasna. Oto dobry arkusz kalkulacyjny dla Ciebie:

metoda Typ danych SQL
int getInt() LICZBOWE, CAŁKOWITE, DZIESIĘTNE
float getFloat() LICZBOWE, CAŁKOWITE, DZIESIĘTNE, FLOAT, RZECZYWISTE
podwójnie pobierzPodwójnie() LICZBOWE, CAŁKOWITE, DZIESIĘTNE, FLOAT, RZECZYWISTE
Data getDate() DATA, GODZINA, ZNACZNIK CZASU
Czas pobierzCzas() DATA, GODZINA, ZNACZNIK CZASU
Pobieranie znacznika czasuZnacznik czasu() DATA, GODZINA, ZNACZNIK CZASU
Ciąg getString() CHAR, VARCHAR

Wśród wszystkich typów SQL można wyraźnie wyróżnić kilka grup:

  • liczby
  • czas
  • linie
  • obiekty bajtowe

Przy okazji, czy zauważyłeś metodę getInt() ?

JDBC i NULL

Czy zauważyłeś, co jest nie tak z metodą getInt() klasy ResultSet ? Spójrzmy jeszcze raz na jego podpis:

int getInt(column)

Ta metoda zwraca int , a nie liczbę całkowitą. Ponieważ w momencie tworzenia JDBC typu Integer jeszcze nie istniał. Ok, powiedzmy. W takim razie mam pytanie:

Mam tabelę w bazie danych, która ma kolumnę INT NULL, która może być INT, ale może też mieć wartość NULL. Jak mogę uzyskać wartość null z tej kolumny?

Nie martw się, wszystko zostało pomyślane dla Ciebie.

Rozwiązanie 1 . Jeśli typ SQL w Javie jest reprezentowany przez typ referencyjny, taki jak Date lub String, nie ma problemu . Zmienne tego typu mogą przyjmować wartości null.

Rozwiązanie drugie . Typy pierwotne nie mogą mieć wartości null, więc metody takie jak getInt() po prostu zwrócą wartość domyślną . Dla int jest to 0, dla float = 0.0f, dla double = 0.0d i tym podobne.

A jak w takim razie zrozumieć, co było w kolumnie: 0 czy NULL? Partia ma odpowiedź na to pytanie.

Rozwiązanie trzecie . Klasa ResultSet ma specjalną metodę wasNull() , która zwraca wartość true, jeśli metoda właśnie zwróciła inną wartość niż NULL .

Wszystko działa dokładnie tak jak napisałem tutaj. Przykład:

ResultSet results = staatement.executeQuery("SELECT * FROM user");
    int level = results.getInt("level");

if (results.wasNull()) {
    System.out.println("Level is null");
} else {
   System.out.println("Level is " + level);
    }

Jeśli miała zwrócić wartość null podczas wywołania metody getInt() , to metoda wasNull() zwróciłaby wartość true, w przeciwnym razie metoda wasNull() zwróciłaby wartość false.

Działa to nie tylko dla typów pierwotnych:

ResultSet results = staatement.executeQuery("SELECT * FROM user");
    String name = results.getString("name");

 	if (results.wasNull()) {
 	    System.out.println("Name is null");
 	} else {
 	   System.out.println("User name is " + name);
    }

To jest oczywiście sztylet. Ale nie ma problemu z NullPointerException . We wszystkim dostrzegaj pozytywy :)

Co jest nie tak z typami danych w JDBC?

Kontynuujmy test. Przyjrzyj się uważnie metodzie getDate(column) ? Co z nim nie tak? Ta metoda ma następujący typ wyniku:

java.sql.Date

Może przechowywać wartość null, co jest wystarczające. Ale i tak coś jest z nim nie tak. Wskazówka! Oto jak wygląda prawidłowy typ daty:

java.util.Date

Mają różne pakiety! Są to na ogół różne rodzaje danych. A oto powód...

Bazy danych od lat 70-tych XX wieku obsługują 3 rodzaje danych do przechowywania czasu:

  • DATA - przechowuje datę: rok, miesiąc, dzień.
  • TIME - przechowuje czas: godziny, minuty, sekundy.
  • TIMESTAMP - przechowuje określony punkt w czasie: datę, godzinę i milisekundy.

Język Java przez pierwsze 10 lat swojego istnienia miał tylko jeden typ danych, java.util.Date , który przechowywał punkt w czasie w formacie UNIX TIME: liczbę milisekund od początku 1970 roku.

Dlatego twórcy standardu JDBC dodali do Javy jeszcze trzy typy danych – specjalnie dla JDBC:

  • java.sql.data
  • java.sql.Time
  • java.sqlTimestamp

I tak metody interfejsu ResultSet zawierają stałe typy danych:

TYP SQL Typ Javy metoda
DATA java.sql.data java.sql.date getDate()
CZAS java.sql.Time java.sql.Time getTime()
ZNAK CZASU znacznik czasu java.sql java.sql.Timestamp getTimestamp()

I to jest typ, który tu widzisz:

„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

Zgadnij, czego tu brakuje? Typy danych, które pojawiły się w Java DateTime API:

  • Data lokalna
  • Czas lokalny
  • LocalDateTime