BD-1st-2.4-lab10.tresc-1.1-Slajd19
Prekompilowane polecenia
Na dotychczasowych slajdach omówiono podstawy pracy z JDBC. Obecnie przejdziemy do omówienia kilku mechanizmów pozwalających na zwiększenie wydajności pracy z SZBD. Pierwszym z tych mechanizmów jest tworzenie prekompilowanych poleceń. Większość aplikacji współpracujących z SZBD, wykonuje jedynie niewielką liczbę różnych poleceń SQL, w których zmieniają się jedynie dane. Jeżeli taka aplikacja za każdym razem przesyła do SZBD polecenie SQL w postaci łańcucha, to polecenie to musi zostać przeanalizowane pod kątem składni, zoptymalizowane i skompilowane. Te operacje zajmują bardzo często nawet 90% czasu realizacji zapytania. Problem ten można rozwiązać tworząc prekompilowane polecenia, w którym można zmieniać jedynie pewne parametry. W JDBC istnieje możliwość tworzenia tego typu poleceń. Każde prekompilowane polecenie jest reprezentowane przez obiekt typu „PreparedStatement” (odpowiednik obiektów typu „Statement” z poprzednich slajdów). Aby utworzyć taki obiekt, należy użyć metody „prepareStatement” interfejsu „Connection”. Jedynym parametrem tej metody jest treść polecenia SQL, w której wszystkie literały, które zmieniają się pomiędzy wywołaniami tego polecenia zastąpiono znakami zapytania. Rozważmy przykład (1). W przykładzie tym deklarowana jest zmienna „stmt” typu „PreparedStatement”, której następnie przypisywany jest wynik działania metody „prepareStatement”. Jako parametr aktualny tej metody przekazano następujące zapytanie: „SELECT nazwisko FROM pracownicy WHERE id_prac=?”. Jak łatwo zauważyć, jest to zapytanie odczytujące nazwisko pracownika, którego identyfikator zostanie podany w klauzuli WHERE. Tutaj, wartość identyfikatora zastąpiono znakiem zapytania, co pozwoli na późniejsze wstawianie w to miejsce różnych wartości. W wyniku działania procedury „prepareStatement” zapytanie zostanie wysłane do SZBD i skompilowane, oraz zostanie zarezerwowany kursor na potrzeby późniejszego jego wykonania. Aby przypisać w miejsce znaku zapytania konkretną wartość należy użyć jednej z metod „setXXX” interfejsu „PreparedStatement”, gdzie XXX oznacza typ wartości zapisywanej do zapytania. Metody te mają nazwy analogiczne do metod „getXXX” stosowanych przy odczytywaniu wyników zapytań. Znajdują tutaj również zastosowanie sugestie dotyczące stosowania odpowiednich metod do odpowiednich typów ANSI SQL.. Pierwszym parametrem metody „setXXX” jest zawsze numer znaku zapytania w prekompilowanym poleceniu SQL (liczony od 1). Drugim parametrem jest wartość, która ma zostać zapisana w miejsce odpowiedniego znaku zapytania. Typ wartości zależy od użytej metody „setXXX”. Kiedy wszystkim znakom zapytania zostanie przypisana odpowiednia wartość można wykonać polecenie za pomocą bezparametrowej metody „executeQuery” (dla zapytań), bądź „executeUpdate” (dla poleceń aktualizacji danych). W wyniku działania tych metod otrzymujemy odpowiednio: obiekt typu „ResultSet”, bądź liczbę typu „int” oznaczającą liczbę wprowadzonych modyfikacji. Rozważmy przykład (2). W przykładzie tym, za pomocą metody „setInt” pierwszemu (i jedynemu) znakowi zapytania przypisujemy wartość 140, a następnie wykonujemy prekompilowane zapytanie. W wyniku wykonania zapytania otrzymujemy zbiór wyników, który znaną już państwu pętlą wypisywany jest na konsoli. Ostatecznie zbiór wyników jest zamykany. Przykład (3) jest identyczny. Jedyną różnicą jest tutaj to, iż za pomocą metody „setInt” podano tutaj inną wartość identyfikatora (170). Ponowne wykonanie zapytania zwróci inny wynik. Jak łatwo zauważyć, na tym przykładzie, jedno polecenie jest wielokrotnie wykonywane, bez konieczności wielokrotnej kompilacji.
Dodatkową zaletą prekompilowanych poleceń jest to, iż programy napisane z ich użyciem są odporne na ataki typu SQL injection .
Pełny kod programu, którego fragmenty przedstawiono na slajdzie, załączono do kursu w pliku JDBCELearning5.java.