JAVA/POSTGRESQL Problem z wykonaniem zapytania do bazy Postgresql

0

Cześć,

Mam następujący problem. Potrzebuję wykonać zapytanie do bazy danych postgresql w javie. Zaznaczam że są to moje początki pisania programów w Javie. Chodzi o to że przy próbie wyciągnięcia wyniku w warunku IF zwracany jest mi błąd. Wygląda na to że zmienna testWyniku obowiązuje tylko w try catch i nie mogę sobie poradzić z tym jak zrobić żeby była widoczna wyżej.


 try {
                    Class.forName("org.postgresql.Driver");

                    // Connection connection = null;

                    //  "jdbc:postgresql://nazwahosta:port/postgres","uzytkownik", "haslo"
                    Connection connection = DriverManager.getConnection(
                            "jdbc:postgresql://localhost:5432/java_magazyn","postgres", "1234");

                    Statement zapytanie = null;
                    ResultSet testWyniku = zapytanie.executeQuery("SELECT count(id) FROM uzytkownicy WHERE login='Mirek' AND password='123'");
                  
                    connection.close();
                    
                    

                } catch (ClassNotFoundException e) {

                    e.printStackTrace();
                    System.out.append("Nie masz sterownika");

                }
                catch (SQLException e )
                {
                    e.printStackTrace();
                    System.out.append("Zle dane");

                }

 tutaj intelli zwraca błąd ----  if (testWyniku){

}

0

Problem, o którym piszesz, nie ma nic wspólnego z bazą danych, zapytaniami itd.
Problem jest po prostu w użyciu bloków (w Twoim przypadku - blok try z wyrażenia try-catch) i zasięgów zmiennych w Java.

1

Zmienną testWyniku deklarujesz w bloku try { }, więc poza tym blokiem nie jest widoczna. Powinieneś poczytać na temat "zakres widoczności zmiennych w javie".

Pomijając zasięg zmiennych, to jest trochę problemów z kodem:

  1. Null Pointer Exception:
 Statement zapytanie = null;
 ResultSet testWyniku = zapytanie.executeQuery("SELECT count(id) FROM uzytkownicy WHERE login='Mirek' AND password='123'");
  1. Jeśli pobierasz jakiś zasób (Connection, PreparedStatement, ResultSet), to należy go zwrócić (bądź użyć automatycznego zwracania zasobów, w kontekście jdbc szukaj pod hasłem: "try-with-resources jdbc")
0
catom napisał(a):

Problem jest po prostu w użyciu bloków (w Twoim przypadku - blok try z wyrażenia try-catch) i zasięgów zmiennych w Java.

Masz jakiś pomysł jak to obejść? Blok try muszę mieć bo obsługuje mi wyjątki a jeśli zrobię zapytanie po za try catch to też nie zadziała. Użycie return zmienna też nie działa.

0

ResultSet testWyniku deklarujesz nad blokiem try catch, a w samym bloku przypisujesz wartość która uzyskasz (bądź nie) po wykonaniu executeQuery.

Poczytaj ze zrozumieniem to co Ci odpowiedzieli koledzy ;)

1

@Mirosław Ziobro: słyszałeś o czyms takim jak try-with-resources ?

0

powrzucaj te localhosty i postgresy w zmienne dla czytelności

tak samo wrzuć to w try-resource by ci automatycznie zamykało działanie po wykonaniu akcji, zaśmiecasz pamięć
np.

try(Connection connection = DriverManager.getConnection("jdbc//localhost:5432/example", "postgres", "postgres")){
...
}

0
Mirosław Ziobro napisał(a):
catom napisał(a):

Problem jest po prostu w użyciu bloków (w Twoim przypadku - blok try z wyrażenia try-catch) i zasięgów zmiennych w Java.

Masz jakiś pomysł jak to obejść? Blok try muszę mieć bo obsługuje mi wyjątki a jeśli zrobię zapytanie po za try catch to też nie zadziała. Użycie return zmienna też nie działa.

Rozwiązań może być kilka, np.:

  1. Nowa metoda, która pobiera z bazy Twój testWyniku i wówczas ta metoda może mieć sygnaturę np. boolean isUserPasswordValid(String userName, String password)
  2. Deklaracja Twojej zmiennej przed wyrażeniem try-catch, by jej zasięg był większy, niż tylko wewnątrz bloku try wyrażenia try-catch.

Uwaga do Twojego sposobu zarządzania hasłami: nie powinno się przechowywać haseł plain-text tylko np. w postaci skrótu wygenerowanego odpowiednią funkcją skrótu (hashującą) jak np. BCrypt czy Argon2 - bardzo dobry artykuł na ten temat OWASP Password Storage Cheat Sheet.
Na Twoje potrzeby nauki pewnie jest to nieistotne, ale NIGDY nie wolno dopuścić, by taka aplikacja została wypuszczona na świat.

Jeszcze uwaga, odnośnie Twojego połączenia:

try {
  // ...
  // jeśli w linijce poniżej wystąpi błąd, to żadno następne polecenie wewnątrz bloku try nie zostanie wykonane, 
  // tj. nie wywoła się np. connection.close()
  // sterowanie zostanie od razu przekonane do odpowiedniego bloku catch (takie go-to)
  ResultSet testWyniku = zapytanie.executeQuery("SELECT count(id) FROM uzytkownicy WHERE login='Mirek' AND password='123'");
  
  connection.close();
} catch (ClassNotFoundException e) {
  // ...
} catch (SQLException e) {
  // ...
}

Dawniej, takie zamykanie I/O robiło się w obsłudze części catch bloku try-catch (+ kolejny blok try-catch :) ), ale od Java 7 (czyli 2011 r.) jest coś takiego jak try-with-resources i tego w Twoim przypakdu proponuję użyć do zamknięcia połączenia.

0

Dziękuję za wszystkie wskazówki na pewno muszę przeczytać o try-with-resources bo tego nie kojarzę z kursu w którym się uczyłem javy. Cały czas brakuje mi praktyki i na pewno potrzebne uporządkowanie i utrwalenie wiedzy. Co do szyfrowania haseł to oczywiście wiem że trzeba szyfrować i zapisywać szyfrowane hasła ale na razie na tym etapie gdzie teraz jestem najpierw chcę wygenerować kod który będzie mi pytał bazę zwracał wyniki w prosty sposób potem będę doszlachetniał aplikację, cały czas się uczę.

1 użytkowników online, w tym zalogowanych: 0, gości: 1