Programowanie w języku Java WYKŁAD



Podobne dokumenty
Metody dostępu do danych

Informatyka I. Standard JDBC Programowanie aplikacji bazodanowych w języku Java

JDBC w LoXiMie. Interfejs Java Database Connectivity dla systemu LoXiM. Adam Michalik 2008

JAVA I BAZY DANYCH. MATERIAŁY:

Podejście obiektowe do relacyjnych baz danych Hibernate.

Informatyka I. Programowanie aplikacji bazodanowych w języku Java. Standard JDBC.

Połączenie z bazą danych

JDBC (Java Database Connectivity vit )

Programowanie w języku Java WYKŁAD

Java i jej wykorzystanie do tworzenia dynamicznych aplikacji Webowych

Mapowanie obiektowo-relacyjne z wykorzystaniem Hibernate

Programowanie obiektowe

Programowanie komputerów. Wykład 10: Dostęp do baz danych z poziomu aplikacji Java. (JDBC Database Access)

Bazy danych wykład dwunasty

JAVA bazy danych. na bazie: Język Java - Podstawy Programowania - Jacek Rumiński

Informacje wstępne Autor Zofia Kruczkiewicz Wzorce oprogramowania 4

Podstawy programowania III WYKŁAD 2

Java Persistence API - zagadnienia zaawansowane

Wzorce logiki dziedziny

Projektowanie oprogramowania. Warstwa integracji z bazą danych oparta na technologii ORM Platforma Java EE Autor: Zofia Kruczkiewicz

JDBC - Obsługa baz danych w języku Java

Podstawy otwartych języków programowania Java Database Connectivity (JDBC)

1 Wprowadzenie do J2EE

PHP: bazy danych, SQL, AJAX i JSON

Aplikacje bazodanowe. dr inż. Arkadiusz Mirakowski

PHP może zostać rozszerzony o mechanizmy dostępu do różnych baz danych:

Plan wykładu. Dostęp do bazy danych. Architektura JDBC. Dostęp do baz danych z aplikacji Java EE

Oracle PL/SQL. Paweł Rajba.

Programowanie w języku Java. Bazy danych SQLite w Javie

Database Connectivity

PRZESTRZENNE BAZY DANYCH WYKŁAD 2

Systemy GIS Tworzenie zapytań w bazach danych

Typy sterowników. Rozdział 21 JDBC. Podstawowe kroki aplikacji. Historia. Program napisany w języku Java JDBC API. Menadżer sterowników JDBC

Wprowadzenie do JDBC z wykorzystaniem bazy H2

JDBC. Plan ćwiczenia. Wywoływanie poleceń SQL z języków programowania. Plan ćwiczenia cd. Wprowadzenie do laboratorium

Wprowadzenie db4o - podstawy db4o - technikalia Przydatne wiadomości. Wprowadzenie. db4o. Norbert Potocki. 1 czerwca Norbert Potocki db4o

Rozdział 9 Obsługa baz danych w języku Java

Technologia informacyjna

METODY PROGRAMOWANIA

4 Web Forms i ASP.NET Web Forms Programowanie Web Forms Możliwości Web Forms Przetwarzanie Web Forms...152

Wzorce dystrybucji i wspólbieżności autonomicznej

akademia androida Składowanie danych część VI

Projektowanie aplikacji z bazami danych

Aplikacje Internetowe, Servlety, JSP i JDBC

Projektowanie obiektowe oprogramowania Wzorce architektury aplikacji (3) Wykład 11 Repository, Unit of Work Wiktor Zychla 2016

Wprowadzenie do technologii JavaServer Faces 2.1 na podstawie

Bazy danych tworzenie aplikacji bazodanowych ORM / JPA

Obiektowy PHP. Czym jest obiekt? Definicja klasy. Składowe klasy pola i metody

Wprowadzenie do technologii JavaServer Faces 2.1 na podstawie

Spis treści. Przedmowa

Blaski i cienie wyzwalaczy w relacyjnych bazach danych. Mgr inż. Andrzej Ptasznik

PL/SQL. Zaawansowane tematy PL/SQL

Bazy danych. Wykład IV SQL - wprowadzenie. Copyrights by Arkadiusz Rzucidło 1

Tworzenie komponentów logiki biznesowej i warstwy dostępu do danych w oparciu o EJB3.0/JPA lub EJB 3.1/JPA2

Ogólny plan przedmiotu. Strony WWW. Literatura BAZY DANYCH. Materiały do wykładu:

Warstwa integracji. wg. D.Alur, J.Crupi, D. Malks, Core J2EE. Wzorce projektowe.

W SQL Serwerze 2008 wprowadzono parametry tablicowe (Table Valued Parameters - TVP).

77. Modelowanie bazy danych rodzaje połączeń relacyjnych, pojęcie klucza obcego.

Kurs programowania aplikacji bazodanowych

Programowanie w języku Java WYKŁAD

Laboratorium nr 4. Temat: SQL część II. Polecenia DML

Uniwersytet Łódzki Wydział Matematyki i Informatyki, Katedra Analizy Nieliniowej. Wstęp. Programowanie w Javie 2. mgr inż.

1.1. System otwartych baz danych ODBC. System otwartych baz danych ODBC. Interfejs ODBC. Interfejs ODBC. System otwartych baz danych ODBC

Programowanie w SQL procedury i funkcje. UWAGA: Proszę nie zapominać o prefiksowaniu nazw obiektów ciągiem [OLIMP\{nr indeksu}] Funkcje użytkownika

Paweł Rajba

JAVA PERSISTENCE API CZĘŚĆ 2 ASPEKTY ZAAWANSOWANE. Waldemar Korłub. Narzędzia i aplikacje Java EE KASK ETI Politechnika Gdańska

Tworzenie aplikacji bazodanowych

Marcin Luckner Politechnika Warszawska Wydział Matematyki i Nauk Informacyjnych

Łączenie z bazą danych przykładowa klasa infpolaczenie import java.sql.drivermanager; import java.sql.connection; import java.sql.

Kurs programowania aplikacji bazodanowych

Języki programowania wysokiego poziomu. PHP cz.4. Bazy danych

Administracja i programowanie pod Microsoft SQL Server 2000

Programowanie w języku Java

T-SQL dla każdego / Alison Balter. Gliwice, cop Spis treści. O autorce 11. Dedykacja 12. Podziękowania 12. Wstęp 15

Oracle11g: Wprowadzenie do SQL

Ćwiczenia laboratoryjne nr 11 Bazy danych i SQL.

Bazy danych 2. Wykład 1

Szkolenie wycofane z oferty. Program szkolenia: Enterprise Java Beans 3.0/3.1

Oracle PL/SQL. Paweł Rajba.

strukturalny język zapytań używany do tworzenia i modyfikowania baz danych oraz do umieszczania i pobierania danych z baz danych

Programowanie obiektowe

Protokół JDBC współpraca z relacyjnymi bazami danych lab3

QUERY język zapytań do tworzenia raportów w AS/400

Programowanie obiektowe

Bazy Danych i Systemy informacyjne Wykład 5. Piotr Syga

Technologie dla aplikacji klasy enterprise. Wprowadzenie. Marek Wojciechowski

Java Database Connectivity

Sprawdzenie czy połączenie przebiegło poprawnie if (mysqli_connect_errno()) { echo Błąd; Połączenie z bazą danych nie powiodło się.

Generowanie dokumentów XML z tabel relacyjnych - funkcje SQLX

Relacyjne bazy danych a XML

Connection con = DriverManager.getConnection(dbUrl, username, passwd);

Wywoływanie metod zdalnych

SQL - Structured Query Language -strukturalny język zapytań SQL SQL SQL SQL

Oracle10g: Programowanie w PL/SQL

Mechanika i Budowa Maszyn II stopień (I stopień / II stopień) ogólnoakademicki (ogólno akademicki / praktyczny)

SYSTEM MONITORINGU PARAMETRÓW WĘZŁÓW PRZECHOWYWANIA DANYCH DLA PROJEKTU KRAJOWY MAGAZYN DANYCH PODRĘCZNIK DEWELOPERA

Bazy danych. Dr inż. Paweł Kasprowski

Instytut Mechaniki i Inżynierii Obliczeniowej Wydział Mechaniczny Technologiczny Politechnika Śląska

Projektowanie systemów baz danych

Transkrypt:

Programowanie w języku Java WYKŁAD dr inż. Piotr Zabawa Certyfikowany Konsultant IBM/Rational e-mail: pzabawa@pk.edu.pl www: http://www.pk.edu.pl/~pzabawa 14.04.2014

WYKŁAD 8 Trwałość w Java cz. 1 Wykład w zakresie JDBC został w znacznej mierze oparty o źródła, których autorem jest Jakob Jenkov dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki

Trwałość w Java Zakład Inżynierii Oprogramowania Celem wykładów poświęconych trwałości w Java nie jest wprowadzenie w zagadnienia relacyjnych baz danych ani w język SQL. Te zagadnienia zostaną opanowane przez studentów w ramach przedmiotów poświęconych bazom danych. Wykład został podzielony na dwie części: JDBC standard wymagający znajomości SQL JPA standard pozwalający uniknąć znajomości SQL Pierwsza część może okazać się przydatna osobom pragnącym tą drogą poznać SQL. Druga część pozwala uniknąć znajomości SQL osobom, które przywiązują większą wagę do tworzonego przez nich oprogramowania niż do samej kwestii składowania danych.

Trwałość w Java Zakład Inżynierii Oprogramowania Wprawdzie relacyjne bazy danych są relatywnie starą technologią, to jednak nadal dominują na rynku. Było wiele prób zastąpienia ich kolejno przez obiektowe, obiektowo-relacyjne, XML owe, a obecnie przez NoSQL owe bazy danych. Ale jak dotąd, żadna z propozycji nie odniosła sukcesu. Dlatego właśnie dominują obecnie relacyjne bazy danych.

Trwałość w Java Zakład Inżynierii Oprogramowania W ramach języka Java trwałość można zapewnić na wiele sposobów: Wprost w Java SE JDBC (Java Database Connectivity) odpowiednik ODBC Z wykorzystaniem frameworków JPA2 (Java Persistence API) standard wykorzystany np. w Hibernate EclipseLink TopLink EJB3 (Enterprise Java Beans) framework wspierający m.in. trwałość Spring Data (Spring Data JPA, Spring Data JDBC Extensions) Seam

Trwałość w Java Zakład Inżynierii Oprogramowania Java posiada wsparcie do obsługi trwałości nie tylko w zakresie relacyjnych baz danych, lecz również NoSQL owych baz danych zyskujących stopniowo na znaczeniu. Dobrym narzędziem jest projekt Spring Data zawierający szereg podprojektów dedykowanych do różnych rodzajów baz danych i wprowadzających ujednolicenie do wszystkich podejść za pomocą podprojektu Spring Data Commons. Jednak na zajęciach skoncentrujemy się jedynie na zagadnieniu mapowania obiektowo-relacyjnego, czyli ORM (Object-Relational Mapping), a więc na dostępie do relacyjnych baz danych.

Trwałość w Java Zakład Inżynierii Oprogramowania Interesować nas będą jedynie dwa z wymienionych wyżej podejść: JDBC niskopoziomowe działanie bliskie SQL, ale za to znaczna kontrola nad implementacją warstwy trwałości JPA2/Hibernate programowanie wysokopoziomowe z możliwością niskopoziomowej optymalizacji, narzędzia forward- i reverseengineering, XML ze strukturą bazy danych Warto mieć na uwadze, że frameworki wprowadzają swoje wysokopoziomowe języki zapytań, zwane ogólnie EL (Expression Languages). Są też dodatkowe języki związane z przeprowadzaniem operacji na relacyjnych bazach danych, np. DDL (Data Definition Language) wykorzystywany m.in. z poziomu narzędzi modelowania w UML do generowania struktury bazy danych z modelu.

Trwałość w Java Zakład Inżynierii Oprogramowania Dawniej wykorzystywany był cały szereg rozwiązań wspierających dostęp do relacyjnych baz danych, jednak z czasem rozwiązania o mniejszym znaczeniu zostały zapomniane lub wchłonięte przez inne rozwiązania. Dobrym przykładem jest standard JPA, który scalił ze sobą rozwiązania takie jak EJB 2 CMP, JDO (nie odniósł sukcesu wśród dostawców frameworków Java EE, ale trafił do standardu), Hibernate oraz TopLink API. Należy również mieć na względzie, że dostępne frameworki nie są tylko implementacją standardów. Dany framework na ogół: Stanowi realizację dużej części, ale nie całości standardu Proponuje własne rozwiązania wykraczające poza standard, a pozwalające na konkurowanie z innymi implementacjami standardu.

Trwałość w Java Zakład Inżynierii Oprogramowania Znaczenie wzorców korporacyjnych w dostępie do danych. Istotną rolę odgrywają następujące architektoniczne wzorce korporacyjne: DAO (Data Access Object) DTO (Data Transfer Object) Active Record Broker SDO = JDO + DTO (Service Data Object = Java Data Object + Data Transfer Object)

Trwałość w Java Zakład Inżynierii Oprogramowania Wartym zainteresowania w kontekście trwałości jest wzorzec architektoniczny DAO (Data Access Object), który zostanie również omówiony ze względu na jego duże znaczenie praktyczne. Wzorzec ten wprowadza dodatkową warstwę (dlatego jest architektoniczny a nie projektowy) do systemu softwerowego. Rzutuje to wprawdzie negatywnie na efektywność operacji na danych, ale nie zawsze ona jest najważniejsza. Wzorzec ten uniezależnia dodatkowo warstwę logiki biznesowej od warstwy danych, co ułatwia wprowadzanie zmian.

Trwałość w Java Zakład Inżynierii Oprogramowania Trudno jednoznacznie przesądzić które z podejść (ORM lub JDBC) jest lepsze. Są zwolennicy jednego lub drugiego, zwolennicy poszczególnych standardów lub narzędzi. Są również tacy, którzy nie wierzą w ORM a nawet w obiektowość i preferują JDBC. Są też tacy, którzy za jedyną słuszną drogę uważają obiektowe bazy danych. Wydaje się jednak, że właściwym podejściem jest stosowanie takiego podejścia, które odpowiada danej osobie. Większym problemem jest dokonanie wyboru dla przedsiębiorstwa wytwarzającego oprogramowanie. Jednak na pewno warto przekonać się o zaletach zarówno jednego jak i drugiego podejścia. W przeciwnym razie trudno podjąć odpowiednią decyzję. Dalej podane zostały argumenty za używaniem (lub nieużywaniem) JPA i ORM.

JDBC

JDBC API jest interfejsem programowym zapewniającym dostęp do relacyjnej bazy danych z poziomu języka Java w sposób niemal niezależny od serwera bazy danych. Stanowi więc mechanizm abstrakcji, którego realizacją są konkretne serwery bazodanowe. Standaryzuje ono następujące operacje: Nawiązanie połączenia z bazą danych Wykonanie zapytań na bazie danych Nawigację po wynikach zapytania Modyfikowanie danych w bazie Standaryzacji nie podlega jednak sam język zapytań SQL jest on różny dla różnych serwerów baz danych.

JDBC zapewnia dostęp niskopoziomowy do bazy danych umożliwiając programiście posługiwanie się językiem zapytań SQL. Język ten zaliczany jest do paradygmatów deklaratywnych oprogramowania. Jego wyrażenia określają cel a nie sposób dojścia do niego. Poszczególni dostawcy serwerów bazodanowych konkurują między sobą m.in. zapewniając zróżnicowane wersje języka SQL. Zatem wykorzystanie standardu JDBC pozwala skorzystać programiście Java w pełni z oferty producentów tych serwerów. Jednak niskopoziomowe operacje mogą być niewygodne w użyciu. Dlatego w kolejnym wykładzie zostaną zaprezentowane inne rozwiązania.

Pakiety standardowej biblioteki Java zawierające JDBC: java.sql javax.sql

Struktura JDBC API: Sterowniki JDBC (JDBC Drivers) Połączenia (Connections) Stwierdzenia (Statements) Zbiory wyników (Result Sets) Podstawowe scenariusze użycia JDBC API: Zapytania kierowane do bazy danych (odczyt danych) Zapytania do bazy danych o meta-dane Update bazy danych Wykonywanie transakcji

JDBC Drivers Zadaniem tych elementów standardu JDBC jest implementacja interfejsów JDBC. Implementacja ta zależy od serwera bazy danych. Jednak interfejsy są od niego niezależne. Można więc podmienić sterownik (podmienić serwer bazy danych) nie zmieniając kodu aplikacji w sytuacji idealnej, ze względu na różnice w funkcjonalności i w SQL.

Connections Po zainicjowaniu drivera umożliwiają one nawiązanie jednego lub więcej połączeń z bazą danych poprzez serwer bazodanowy. Całą komunikacja aplikacji w Java z bazą danych przebiega wyłącznie poprzez Connections.

Statements Stwierdzenia służą do wykonywania zapytań o dane i wprowadzania zmian do danych w bazie. Istnieje kilka różnych stwierdzeń pozwalających na wykonywanie różnych zapytań.

Result Sets W wyniku wykonania zapytania można uzyskać jego wynik w postaci ResultSet. Klasa ta umożliwia nawigowanie po jej obiektach w celu uzyskania wyników zapytania z poziomu języka Java, a więc w sposób obiektowy.

Podstawowe scenariusze Zapytania kierowane do bazy danych noszą one nazwę zapytań (query) i polegają wyłącznie na odczycie danych z bazy. Są najczęściej używanymi operacjami. Zapytania do bazy danych o meta-dane polegają na uzyskaniu od bazy danych informacji o jej strukturze (tabelach, kolumnach, typach danych, relacjach); są relacyjno-bazo-danowym odpowiednikiem klasowoobiektowego mechanizmu refleksji dostępnego w Java Update bazy danych operacje te polegają na zapisie do bazy danych; zapis może dotyczyć wstawiania nowych rekordów lub modyfikowania istniejących Wykonywanie transakcji polega na łącznym wykonywaniu wielu operacji na bazie danych z jednoczesną gwarancją wykonania ich wszystkich (sukces) lub niewykonania żadnej z nich (porażka)

źródło: Jakob Jenkov

Typy sterowników JDBC JDBC-ODBC bridge driver wsparcie usunięte w Java 8! Java + Native code driver All Java + Middleware translation driver All Java driver jest to jedyny obecnie wspierany typ sterownika. Łączy aplikację bezpośrednio z bazą danych i jest specyficzny dla poszczególnych serwerów. Jest też najbardziej efektywnym (performance) rodzajem sterownika. źródło: Jakob Jenkov

Dalej zostały omówione typowe kroki spotykane w aplikacjach wykorzystujących JDBC.

Załadowanie sterownika (od Java 6 automatycznie!) Należy je wykonać raz. Przykładowy kod: Class.forName("com.mysql.jdbc.Driver"); Korzystamy z mechanizmu refleksji ładując poprzez standardowego class loader a klasę sterownika określoną przez nazwę. Klasa ta zależy od serwera bazy danych. Powyższy przykład ładuje sterownik JDBC serwera MySQL.

Otwarcie połączenia z bazą danych Wykorzystujemy klasę java.sql.drivermanager. Przykład dla MySQL: String url = "jdbc:mysql://[host]:[port]/db_name"; String user = uname"; String password = passwd"; Connection connection = DriverManager.getConnection(url, user, password); [host] - jeśli pominięty, to localhost [port] - domyślny port dla serwera MySQL, to 3306

Jawne zamknięcie połączenia Jeśli nie zamierzamy już korzystać z danego połączenia z bazą danych, to powinniśmy je zamknąć w celu zwolnienia zasobów. Możemy to wykonać za pomocą metody: connection.close();

Zapytania o dane (odczyt) Jeśli mamy otwarte połączenie z bazą danych możemy skierować do niej zapytanie w następujący sposób: Statement statement = connection.createstatement(); String sql = "select * from people"; ResultSet result = statement.executequery(sql); Wyniki zapytania zostają umieszczone w klasie ResultSet, którą możemy iterować wierszami (rekordami): while(result.next()) { } String name = result.getstring("name"); long age = result.getlong ("age");

Dla danego wiersza można uzyskać dostęp do danych w kolumnie za pomocą jednej z metod: getx() gdzie: X klasa wrapera typu prostego Dostęp do poszczególnych kolumn tabeli może być za pomocą nazwy kolumny lub indeksu kolumny, co pokazano poniżej.

getstring(<column_name>); getlong(<column_name>); getint(<column_name>); getdouble(<column_name>); getbigdecimal(<column_name>); getstring(<column_index>); getlong(<column_index>); getint(<column_index>); getdouble(<column_index>); getbigdecimal(<column_index>);

Indeks kolumny w ramach ResultSet można uzyskać po nazwie za pomocą wywołania następującej metody: int columnindex = result.findcolumn("columnname"); Dostęp za pomocą indeksu jest szybszy. Po skorzystaniu z wyników zapytania należy zwolnić zasoby: result.close(); statement.close(); Można wywołania te umieścić w bloku finally.

try(statement statement = connection.createstatement()) { String sql = "select * from people"; try(resultset result = statement.executequery(sql)) { ResultSet result = statement.executequery(sql); while(result.next()) { String name = result.getstring("name"); long age = result.getlong("age"); System.out.println(name); System.out.println(age); } } }

Zapis do bazy Są dwa rodzaje zapisów: Aktualizacja rekordu Usunięcie rekordu Do wykonania obu rodzajów zapisu wykorzystywana jest metoda: executeupdate()

Zmiana rekordów Statement statement = connection.createstatement(); String sql = "update people set name='john' where id=123"; int rowsaffected = statement.executeupdate(sql); Metoda executeupdate() zwraca informację o ilości zmienionych rekordów.

Usunięcie rekordów Statement statement = connection.createstatement(); String sql = "delete from people where id=123"; int rowsaffected = statement.executeupdate(sql); Metoda executeupdate() zwraca informację o ilości zmienionych rekordów.

ResultSet Klasa ResultSet zawiera wynik zapytania. Można go sobie wyobrazić jako tabelę z rekordami w wierszach i polami rekordów w kolumnach. Należy pamiętać, że komórki tabeli mogą zawierać dane, a niektóre wartość null reprezentująca brak danych (nie wszystkie pola w tabeli relacyjnej bazy danych są wymagane). Należy mieć na uwadze fakt, że nie można uzyskać w sposób bezpośredni informacji o ilości wierszy w ResultSet. Są dwa sposoby utworzenia obiektu tej klasy: Przez wykonanie zapytania (Statement) Przez wykonanie przygotowanego zapytania (PreparedStatement)

Wykonanie Statement: Statement statement = connection.createstatement(); ResultSet result = statement.executequery("select * from people"); Wykonanie PreparedStatement: String sql = "select * from people"; PreparedStatement statement = connection.preparestatement(sql); ResultSet result = statement.executequery();

W czasie tworzenia stwierdzenia możemy sterować następującymi parametrami tworzonego przez niego obiektu klasy ResultSet: Type Concurrency Holdability Statement statement = connection.createstatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_OVER_COMMIT ); PreparedStatement statement = connection.preparestatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_OVER_COMMIT );

Typy ResultSet ResultSet.TYPE_FORWARD_ONLY Oznacza, że nie jest możliwe iterowanie w przeciwnym kierunku niż od pierwszego do ostatniego rekordu. Jest domyślny. ResultSet.TYPE_SCROLL_INSENSITIVE Można iterować w dowolnym kierunku i przeskakiwać do dowolnego rekordu, ale zmiana danych w bazie danych nie zostanie odzwierciedlona w obiekcie klasy ResultSet po jego utworzeniu. ResultSet.TYPE_SCROLL_SENSITIVE Można iterować w dowolnym kierunku i przeskakiwać do dowolnego rekordu. Zmiana danych w bazie danych zostanie odzwierciedlona w obiekcie klasy ResultSet po jego utworzeniu.

Metody nawigacji Zakład Inżynierii Oprogramowania Dostępność poniżej przedstawionych metod zależy od serwera bazy danych, sterownika JDBC oraz typu ResultSet. Metoda absolute() afterlast() beforefirst() first() last() next() previous() Opis Ustawia kursor we wskazanej pozycji względem początkowego rekordu Ustawia kursor na końcu (poza zakresem) Ustawia kursor na początku (poza zakresem) Ustawia kursor na pierwszy rekord Ustawia kursor na ostatni rekord Przesuwa kursor do następnej pozycji Przesuwa kursor do poprzedniej pozycji relative() Przesuwa kursor z aktualnej pozycji o wskazaną ilość rekordów (+/-)

Metody uzyskiwania informacji o aktualnej pozycji kursora Metoda getrow() gettype() isafterlast() isbeforefirst() isfirst() Opis Zwraca numer wiersza dla aktualnej pozycji kursora Zwraca informację o typie ResultSet Zwraca true jeśli kursor wyszedł poza ostatni rekord Zwraca true jeśli kursor jest przed pierwszym rekordem Zwraca true jeśli kursor wskazuje na pierwszy rekord

Metoda odświeżająca aktualny wiersz w ResultSet, jeśli ResultSet jest typu ResultSet.TYPE_SCROLL_SENSITIVE Metoda refreshrow() Opis Aktualizuje wartości pól rekordu w ResultSet na podstawie aktualnych wartości rekordu w bazie danych

Współbieżność ResultSet Dostępne są dwa poziomy współbieżności: ResultSet.CONCUR_READ_ONLY ResultSet.CONCUR_UPDATABLE Jeśli ResultSet jest określony jako, to można dokonać aktualizacji poszczególnych pól danego rekordu za pomocą metod updatex() analogicznych do getx(). Do pól można odwoływać się po nazwie lub po indeksie kolumny. Należy pamiętać o wywołaniu metody result.updaterow() dla całego rekordu po aktualizacji jego pól. Metoda ta dokonuje aktualizacji danych w bazie pod warunkiem, że nie została wywołana wewnątrz transakcji. Przykłady metod updatex() podano poniżej.

updatestring(<column_name>); updatelong(<column_name>); updateint(<column_name>); updatedouble(<column_name>); updatebigdecimal(<column_name>); updatestring(<column_index>); updatelong(<column_index>); updateint(<column_index>); updatedouble(<column_index>); updatebigdecimal(<column_index>);

Wstawianie wierszy do ResultSet Aby wstawić wiersz do ResultSet należy wykonać następujące kroki: Wywołać ResultSet.moveToInsertRow() Zaktualizować wartości kolumn w tym wierszu Wywołać ResultSet.insertRow()

ResultSet Holdability Cecha ta określa czy po dokonaniu commitu obiektu ResultSet do bazy danych następuje destrukcja obiektu ResultSet czy nie. Dostępność tej funkcjonalności dla danego sterownika można sprawdzić wywołaniem metody: DatabaseMetaData.supportsResultSetHoldability(int holdability) Rodzaje holdability: ResultSet.CLOSE_CURSORS_OVER_COMMIT ResultSet.HOLD_CURSORS_OVER_COMMIT

PreparedStatement Powody stosowania: Łatwość wprowadzania parametrów do zapytania SQL Łatwość ponownego użycia z nowymi parametrami Możliwość zwiększenia wydajności wykonywanych komend Ułatwienie wykonywania batch updates.

Przykład: String sql = "update people set firstname=?, lastname=? where id=?"; PreparedStatement preparedstatement = connection.preparestatement(sql); preparedstatement.setstring(1, "Gary"); preparedstatement.setstring(2, "Larson"); preparedstatement.setlong (3, 123); int rowsaffected = preparedstatement.executeupdate();

Zwiększenie efektywności zapytań: Poprzez cache owanie zapytań po stronie sterownika Poprzez współdzielenie zapytań pomiędzy aplikacjami Java Poprzez cache owanie zapytań po stronie serwera bazy danych zwiększenie wydajności poprzez minimalizację analizy planu wykonania zapytań

Batch Updates Ten tryb pracy z bazą danych polega na przesyłaniu do niej wielu komend za jednym razem. Nie ma sensu stosowanie go dla zapytań (odczytu), lecz jedynie dla zapisu. Można wykonywać takie update y za pomocą: Statement PreparedStatement

Statement Statement statement = null; try{ statement = connection.createstatement(); statement.addbatch("update people set firstname='john' where id=123"); statement.addbatch("update people set firstname='eric' where id=456"); statement.addbatch("update people set firstname='may' where id=789"); int[] recordsaffected = statement.executebatch(); } finally { if(statement!= null) statement.close(); }

PreparedStetment String sql = "update people set firstname=?, lastname=? where id=?"; PreparedStatement preparedstatement = null; try{ preparedstatement = connection.preparestatement(sql); preparedstatement.setstring(1, "Gary"); preparedstatement.setstring(2, "Larson"); preparedstatement.setlong (3, 123); preparedstatement.addbatch(); preparedstatement.setstring(1, "Stan"); preparedstatement.setstring(2, "Lee"); preparedstatement.setlong (3, 456); preparedstatement.addbatch(); int[] affectedrecords = preparedstatement.executebatch(); } finally { if(preparedstatement!= null) preparedstatement.close(); }

Ryzyko stosowania batch updates polega na tym, że część komend może się udać, a część nie i wtedy nie wiadomo jak postąpić w kodzie. Dlatego dobrą praktyką wykonywania batch updates jest wykonywanie ich w ramach transakcji.

Transakcje Służą określeniu, który zestaw operacji ma być traktowany łącznie jako operacja atomowa. Jeśli wszystkie operacje składowe zakończą się sukcesem, to zestaw operacji zostanie wykonany w całości. Jeśli któraś z operacji składowych nie powiedzie się, to nie zostanie wykonana żadna z operacji.

Przykład transakcji Connection connection =... try { connection.setautocommit(false); // create and execute statements etc. connection.commit(); } catch(exception e) { connection.rollback(); } finally { if(connection!= null) connection.close(); }

Procedury składowane Jest to rozwiązanie dostępne po stronie bazy danych. Służy do przechowywania procedur zawierających komendy w celu zwiększenia wydajności. Utworzenie komendy: CallableStatement callablestatement = connection.preparecall("{call calculatestatistics(?,?)}"); albo CallableStatement callablestatement = connection.preparecall("{call calculatestatistics(?,?)}", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_OVER_COMMIT );

Java 7 Dodano instrukcję try-with-resources w celu zautomatyzowania zamykania zasobów znanego z wykładu dotyczącego wyjątków przykład z zamykaniem strumieni. Połączenie z bazą danych traktowane jest jako zasób. Przykład na następnym slajdzie Dodano interfejs RowSetFactory i klasę RowSetProvider pozwalające na uzyskanie każdego z rodzajów RowSet dostępnych dla danego JDBC Driver, a więc uwzględniających specyfikę serwera bazy danych. Przykład na kolejnym slajdzie

Przykład: public static void samplequeryproc(connection samplecon) throws SQLException { String samplequery = "select ROLLNO, NAME, ADDRESS from STUDENT"; try (Statement samplestmt = samplecon.createstatement()) { ResultSet sampleresultset = samplestmt.executequery(samplequery); while (rs.next()) { int rollno = sampleresultset.getint("rollno"); } } } String studentname = sampleresultset.getstring("name"); String studentaddress = sampleresultset.getstring("address"); System.out.println( ROLLNO: + rollno + " NAME: " + studentname + " ADDRESS: " + studentaddress);

public void samplemethod(string sampleusername, String samplepassword) throws SQLException { } RowSetFactory samplerowsetfactory = null; JdbcRowSet samplerowset = null; try { samplerowsetfactory = RowSetProvider.newFactory(); samplerowset = samplerowsetfactory.createjdbcrowset(); samplerowset.seturl("jdbc:sampledriver:sampleattribute"); samplerowset.setusername(sampleusername); samplerowset.setpassword(samplepassword); samplerowset.setcommand(""select ROLLNO, NAME, ADDRESS from STUDENT"); samplerowset.execute(); } catch(exception e) { }

Parametry wyjściowe z procedury składowanej Procedura składowana może zwracać wartości. Przykład korzystania z parametrów wyjściowych procedury składowanej podano na następnym slajdzie.

CallableStatement callablestatement = connection.preparecall("{call calculatestatistics(?,?)}"); callablestatement.setstring(1, "param1"); callablestatement.setint (2, 123); callablestatement.registeroutparameter(1, java.sql.types.varchar); callablestatement.registeroutparameter(2, java.sql.types.integer); ResultSet result = callablestatement.executequery(); // najpierw ResultSet while(result.next()) {... } // potem OUT parameters String out1 = callablestatement.getstring(1); int out2 = callablestatement.getint (2);

Należy najpierw analizować ResultSet, a dopiero potem parametry wyjściowe dobra praktyka związana z kompatybilnością z różnymi serwerami bazodanowymi.

DatabaseMetaData Metody z tej grupy służą uzyskaniu ogólnych informacji o bazie danych. Uzyskanie obiektu meta-danych: DatabaseMetaData databasemetadata = connection.getmetadata(); Uzyskanie danych o serwerze bazodanowym: int majorversion = databasemetadata.getdatabasemajorversion(); int minorversion = databasemetadata.getdatabaseminorversion(); String productname = databasemetadata.getdatabaseproductname(); String productversion = databasemetadata.getdatabaseproductversion(); Uzyskanie danych o sterowniku: int drivermajorversion = databasemetadata.getdrivermajorversion(); int driverminorversion = databasemetadata.getdriverminorversion();

Wylistowanie tabel: String catalog = null; String schemapattern = null; String tablenamepattern = null; String[] types = null; ResultSet result = databasemetadata.gettables( catalog, schemapattern, tablenamepattern, types ); while(result.next()) { String tablename = result.getstring(3); } Wylistowanie kolumn w tabeli: String catalog = null; String schemapattern = null; String tablenamepattern = "my_table"; String columnnamepattern = null; ResultSet result = databasemetadata.getcolumns( catalog, schemapattern, tablenamepattern, columnnamepattern); while(result.next()){ String columnname = result.getstring(4); int columntype = result.getint(5); }

Uzyskanie informacji o kluczu prywatnym tabeli String catalog = null; String schema = null; String tablename = "my_table"; ResultSet result = databasemetadata.getprimarykeys( catalog, schema, tablename); while(result.next()) String columnname = result.getstring(4); Dla kluczy złożonych zwrócony ResultSet może mieć wiele wierszy.

Sprawdzanie jakie funkcjonalności są wspierane przez dany sterownik databasemetadata.supportsgetgeneratedkeys(); databasemetadata.supportsgroupby(); databasemetadata.supportsouterjoins();

Ustawianie wartości parametrów wywołania metody składowanej: callablestatement.setstring(1, "param1"); callablestatement.setint (2, 123); Wykonanie metody składowanej: ResultSet result = callablestatement.executequery(); albo callablestatement.executeupdate();

Trwałość w Java 10 dobrych praktyk JDBC Stosować PreparedStatement Stosować ConnectionPool Wyłączać tryb auto commit Stosować JDBC Batch Update W dostępie do ResultSet stosować nazwy kolumn aby uniknąć wyjątku invalidcolumindexerror Stosować zmienne Bind zamiast konkatenacji String ów Zawsze zamykać Statement, PreparedStatement i Connection Wybierać odpowiedni sterownik JDBC dla tworzonej aplikacji Stosować standardowe zapytania i unikać stosowania wyrażeń specyficznych dla serwera bazy danych o ile to możliwe Stosować właściwą metodę getxxx()

Koniec dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki