1. Wprowadzenie
Plik PDF tego dokumentu jest dostępny pod adresem |TUTAJ|.
Przykłady zawarte w tym dokumencie są dostępne pod adresem |TUTAJ|.
1.1. Contenu
W niniejszym dokumencie zamierzamy przeanalizować różne konfiguracje eksploatacji bazy danych. Rozważmy następującą architekturę warstwową:
![]() |
Przebieg wykonania przebiega od lewej do prawej:
- jako pierwsza wykonywana jest jedna z klas warstwy [ui] (Use Interface). Klasa ta utworzy instancje warstw [metier] i [dao]. Jeśli warstwa [ui] jest interfejsem graficznym, czeka następnie na działania użytkownika. Działanie użytkownika może spowodować wykonanie metod we wszystkich warstwach architektury, aż do bazy danych. Wynik tych operacji jest przedstawiany użytkownikowi w takiej czy innej formie;
Rola poszczególnych warstw mogłaby wyglądać następująco:
- warstwa [JDBC] (Java DataBase Connectivity) stanowi uniwersalny interfejs dostępu do baz danych. Zawsze udostępnia ten sam interfejs warstwie [DAO]. W przypadku zmiany warstwy SGBD wystarczy zmienić sterownik JDBC. Warstwa [DAO] pozostaje niezmieniona, o ile przestrzegano określonych zasad. Trudno jest jednak zapewnić 100% przenośności między wersjami SGBD, ponieważ często zawierają one znaczną część zastrzeżonego kodu SQL, którego trudno zignorować, ponieważ często zapewnia on wzrost wydajności. Gdy tylko zastosuje się zastrzeżony kod SQL, przenoszenie między wersjami SGBD nie jest już możliwe. Ponadto wersje SGBD często charakteryzują się odmiennymi zasadami automatycznego generowania kluczy głównych oraz różnymi słowami zastrzeżonymi w poszczególnych wersjach. W niniejszym dokumencie udało się jednak przenieść badaną architekturę JDBC na sześć różnych instancji SGBD, przyjmując, że dla każdej z nich istnieje osobny projekt konfiguracyjny;
- warstwa [DAO] udostępnia interfejs dostępu do danych konkretnej wykorzystywanej bazy danych (należy odróżnić ją od interfejsu JDBC, który udostępnia metody obowiązujące dla wszystkich instancji SGBD);
- warstwa [métier] realizuje reguły zarządzania lub reguły biznesowe aplikacji.
- Jako dane wejściowe wykorzystuje dane pochodzące z bazy danych za pośrednictwem warstwy [dao] i/lub dane od użytkownika przekazywane jej przez warstwę [ui];
- generuje dane, które może zapisać w bazie danych za pośrednictwem warstwy [dao] i/lub przekazać z powrotem do warstwy [ui], która ją wywołała, w celu wyświetlenia użytkownikowi;
- warstwa [ui] jest warstwą, która wykonuje działania użytkownika i zwraca mu ich wyniki;
W powyższym przykładzie warstwa [DAO] wysyła żądania SQL do warstwy [JDBC] w celu wykonania w warstwie SGBD. Od kilku lat (od 2006 r.) architektura ta może ewoluować w następujący sposób:
![]() |
Obecnie to warstwa JPA (Java Persistence API) wysyła zapytania SQL do warstwy JDBC i odbiera od niej wyniki. Warstwa [JPA] udostępnia warstwie [DAO] operacje służące do zapisywania, modyfikowania, usuwania i pobierania obiektów. Warstwa [DAO] nie wysyła już poleceń SQL. To podejście jest bardziej przenośne, ponieważ implementacje JPA obsługują różnice w stosunku do SGBD, ale jest ono wolniejsze niż technologia JDBC. Przeprowadzimy testy wydajności, aby to wykazać. Technologia JPA formalizuje pracę wykonaną przez framework Hibernate [http://hibernate.org/] wiele lat temu.
Przeanalizujemy dwie warstwy [DAO] w jednej z dwóch następujących architektur:
![]() |
![]() |
Warunkiem będzie, aby warstwy [DAO1] i [DAO2] implementowały ten sam interfejs [IDAO]. Dzięki temu test [JUnitTestsDao] będzie taki sam dla obu konfiguracji i pozwoli nam porównać wydajność. Warstwa [DAO1] zostanie zaimplementowana przy użyciu Spring JDBC, a warstwa [DAO2] przy użyciu Spring JPA;
Po wykonaniu tych czynności udostępnimy interfejs [IDAO] w sieci w następujący sposób:
![]() |
- w przypadku [1] warstwa [IDAO] jest udostępniana w sieci WWW za pośrednictwem warstwy internetowej [2] zaimplementowanej przez Spring MVC. To właśnie interfejs [IDAO] jest udostępniany, a my stworzymy dwie wersje usługi internetowej w zależności od tego, czy interfejs ten jest zaimplementowany w architekturze [DAO-JDBC], czy [DAO-JPA-JDBC];
- W warstwie [B] klient zdalny korzysta z interfejsów URL udostępnianych przez serwis internetowy, które zapewniają dostęp do metod warstwy [IDAO-serveur]. Zadbamy o to, aby warstwa [DAO-Client] [3] implementowała interfejs [IDAO-serveur] [1]. Umożliwi nam to wykorzystanie tego samego testu [JUnitTestsDao], który został już dwukrotnie użyty w [4];
- w [3] warstwa [DAO-client] zostanie zaimplementowana przy użyciu Springa RestTemplate;
Po wykonaniu tych czynności zabezpieczymy dostęp do serwisu internetowego:
![]() |
- w [5] żądanie klienta HTTP przechodzi przez warstwę uwierzytelniania zaimplementowaną przy użyciu Spring Security;
Po wykonaniu tej czynności przekształcimy poprzednią architekturę w następującą:
![]() |
- w [3] aplikacja kliencka sama w sobie jest aplikacją internetową. Będzie ona wyświetlać formularz [5] umożliwiający wysyłanie zapytań do URL zabezpieczonej usługi internetowej. Dostęp do zabezpieczonej usługi internetowej HTTP będzie realizowany za pośrednictwem warstwy [DAO-client-js] zaimplementowanej w języku JavaScript. Architektura ta wykorzystuje tzw. żądania międzydomenowe:
- serwis internetowy [2] udostępnia URL w postaci [http://machine1:port1/];
- klientowa aplikacja internetowa [3] jest pobierana z serwera URL lub [http://machine2:port2/]. Jeśli [http://machine2:port2/] nie jest identyczny z [http://machine1:port1/] (ta sama maszyna, ten sam port), wówczas przeglądarka klienta zablokuje wywołania HTTP z warstwy [DAO-client-js]. Aby rozwiązać ten problem, serwis internetowy musi zezwolić na żądania międzydomenowe. Zobaczymy, jak to zrobić;
Przedstawione projekty zostały przetestowane z następującymi sześcioma instancjami SGBD:
- MySQL 5 Community Edition;
- SQL Server 2014 Express;
- PostgreSQL 9.4;
- Oracle Express 11g wersja 2;
- IBM DB2 Express-C 10.5;
- Firebird 2.5.4;
Dla każdego z tych SGBD opracowano cztery różne warstwy [DAO]:
- warstwę zaimplementowaną przy użyciu Springa JDBC;
- warstwę zaimplementowaną przy użyciu Spring JPA oraz dostawcy JPA Hibernate;
- warstwa zaimplementowana przy użyciu Springa JPA oraz dostawcy JPA EclipseLink;
- warstwa zaimplementowana przy użyciu Springa JPA oraz dostawcy JPA i OpenJPA;
Przedstawiono tu zatem zestaw dwudziestu czterech różnych konfiguracji. Dołożono dużych starań, aby uprościć kod:
- większość kodu została napisana tylko raz. Opiera się on na dwóch projektach konfiguracyjnych Maven:
- jeden konfiguruje warstwę JDBC;
- drugi konfiguruje warstwę JPA;
![]() |
![]() |
Projekt konfiguracyjny Maven dla warstwy JDBC [1] konkretnego SGBD składa się z dwóch elementów:
- zaimportowanie archiwum sterownika JDBC;
- zdefiniowanie identyfikatorów dostępu do wykorzystywanej bazy danych oraz różnych poleceń SQL, które warstwa [DAO1] będzie wysyłać do sterownika JDBC. Mimo że SQL jest standardizowany, napotkano problemy z przenoszalnością, głównie z powodu obecności w zapytaniach nazw tabel/kolumn, które okazały się być słowami kluczowymi zabronionymi w niektórych SGBD (tabela ROLES dla DB2, kolumna PASSWORD dla Firebird). Ponadto, mimo że nazwa kolumny zazwyczaj nie rozróżnia wielkości liter (wielkie/małe), napotkano problem z PostgreSQL w przypadku kolumny ID klucza głównego w tabelach. System wymagał, aby kolumna ta nosiła nazwę id, pisana małymi literami. Są to typowe przykłady nieoczekiwanych problemów związanych z przenoszeniem kodu;
Trzy projekty Maven konfigurujące warstwę JPA, [2] dla konkretnego SGBD również składają się z dwóch elementów:
- import archiwum implementacji JPA;
- skonfigurowanie implementacji JPA wykorzystywanej dla konkretnego podłączonego SGBD. W rzeczywistości to warstwa JPA wysyła polecenia SQL do warstwy JDBC. Aby działać skutecznie, musi ona znać SGBD, aby móc wysłać do niego polecenia SQL, które ten rozpozna. Polecenia te będą mogły wykorzystywać SQL, będący właścicielem tego SGBD, a także jego szczególne cechy (typy danych, sekwencje, wyzwalacze, procedury, automatyczne generowanie kluczy głównych itp.);
W ten sposób mamy dwadzieścia cztery projekty (4 konfiguracje × 6 SGBD) konfiguracyjne Maven, na których będą opierać się wszystkie pozostałe projekty związane z obsługą bazy danych. W powyższych schematach warstwy [DAO1] i [DAO2] oferują ten sam interfejs, dlatego 24 konfiguracje obu powyższych architektur zostaną przetestowane za pomocą jednej klasy testowej [JUnitTestsDao]. Po zweryfikowaniu tych architektur nie ma już żadnych trudności:
- projekt Maven dotyczący publikacji bazy danych w sieci opiera się na tych dwóch architekturach. Istnieje zatem również 24 możliwe konfiguracje;
- projekt Maven dotyczący zabezpieczenia dostępu do serwisu internetowego opiera się na poprzednim projekcie i również ma 24 możliwe konfiguracje;
- wreszcie projekt Maven umożliwiający żądania międzydomenowe do zabezpieczonej usługi internetowej opiera się na poprzednim projekcie i również ma 24 możliwe konfiguracje;
Badanie przeprowadzono z wykorzystaniem SGBD, MySQL5 oraz implementacji Hibernate o numerze JPA. Następnie przeprowadzono portowanie na implementacje JPA (Eclipselink) oraz OpenJPA. Następnie dokonuje się przeniesienia do pozostałych baz danych (PostgresQL, Oracle, SQL Server, DB2, Firebird).
Kurs ten jest przeznaczony dla początkujących. Wyjaśniono większość wykorzystywanych pojęć. Nie jest wymagana znajomość ani programowania baz danych, ani programowania stron internetowych. Konieczna jest jednak solidna znajomość języka SQL, ponieważ używane zapytania SQL nie są wyjaśnione.
Aby zrozumieć przykłady, potrzebna jest podstawowa znajomość języka Java, którą można zdobyć na dowolnym kursie wprowadzającym do tego języka. Wystarczą dwa pierwsze rozdziały dokumentu [Introduction au langage Java]. Jest to stary dokument (z 1998 r., zaktualizowany w 2002 r.), ale zawiera podstawowe informacje. Aby uzyskać pełny kurs, można zapoznać się z obszerną książką Jeana-Marie Doudouxa [http://www.jmdoudoux.fr/java].
Niniejszy dokument nie ma charakteru wyczerpującego. Ma on jedynie na celu przedstawienie metodologii oraz kodu, który można ponownie wykorzystać w podobnych kontekstach. Dokument został napisany w taki sposób, aby można go było czytać bez konieczności korzystania z komputera. Dlatego też zamieszczono w nim wiele zrzutów ekranu.
Chociaż dokument ten nie obejmuje wszystkich możliwości języka Java ani wszystkich obszarów jego zastosowania, może służyć jako materiał do nauki tego języka. Jeśli początkujący czytelnik zapozna się z niniejszym dokumentem, choć nie w całości, osiągnie poziom „zaawansowanej znajomości języka Java” zarówno w zakresie posługiwania się samym językiem, jak i frameworkiem Spring. Będzie mógł wówczas kontynuować naukę języka Java, korzystając z następujących publikacji:
- [Spring MVC et Thymeleaf par l'exemple] [http://tahe.developpez.com/java/springmvc-thymeleaf], które kontynuują naukę ekosystemu Spring, przedstawiając jego gałąź „programowania internetowego MVC”;
- [Tutoriel AngularJS / Spring MVC] [http://tahe.developpez.com/angularjs-spring4], które przedstawia architekturę internetową typu klient/serwer, gdzie klient jest zaimplementowany przy użyciu frameworka [AngularJS], a serwer przy użyciu [Spring MVC];
- [Introduction à Java EE], który odchodzi od środowiska Spring na rzecz architektury internetowej opartej na JSF (Java Server Faces) oraz EJB (Enterprise Java Bean);
- [Introduction à la programmation des tablettes Android] [http://tahe.developpez.com/android/exemples-intellij-aa], opisujący architekturę klient-serwer, w której klientem jest tablet z systemem Android, a serwerem – usługa internetowa zaimplementowana przy użyciu Springa MVC;
1.2. Sources
Niniejszy dokument opiera się na dwóch głównych źródłach:
- [ref1] : od [Spring MVC et Thymeleaf par l'exemple] do URL i [http://tahe.developpez.com/java/springmvc-thymeleaf/]. Niniejszy dokument wykorzystuje, w oparciu o inną bazę danych, pracę wykonaną i przedstawioną w dokumencie [ref1]. Po prostu wyrywa ją z kontekstu programowania internetowego z wykorzystaniem Springa (MVC). Ponieważ uznałem, że kod i metodologia wykorzystane w [ref1] do udostępnienia bazy danych w sieci są nadające się do ponownego wykorzystania, postanowiłem stworzyć z nich osobny dokument;
- [ref2] : od [Persistance Java par la pratique] do URL i [http://tahe.developpez.com/java/jpa];
Aby pogłębić wiedzę na temat Springa, można skorzystać z następujących materiałów:
- dokument referencyjny frameworka Spring [http://docs.spring.io/spring/docs/current/spring-framework-reference/pdf/spring-framework-reference.pdf];
- liczne samouczki dotyczące Springa można znaleźć pod adresem URL [http://spring.io/guides];
- strona internetowa [developpez.com] poświęcona frameworkowi Spring [http://spring.developpez.com/];
- samouczek [http://www.tutorialspoint.com/spring/spring_tutorial.pdf];
Czytelnik, który nie ma wystarczającej wiedzy na temat SQL, może zapoznać się z podstawami dzięki publikacji [Introduction au langage SQL avec le SGBD Firebird] dostępnej pod adresem URL [http://tahe.developpez.com/divers/sql-firebird/].
1.3. Wykorzystane narzędzia
Poniższe przykłady zostały przetestowane w następującym środowisku:
- komputer z systemem Windows 8.1 Pro 64-bitowym;
- JDK 1.8 (punkt 23.1);
- IDE Spring Tool Suite 3.6.3 (punkt 1);
- przeglądarka Chrome (inne przeglądarki nie były używane);
- rozszerzenie Chrome [Advanced Rest Client] (punkt 1);
- SGBD MySQL 5.6 Community Edition (punkt 23.4);
- SGBD SQL Server 2014 Express (ustęp 23.9);
- SGBD PostgreSQL 9.4 (punkt 23.7);
- SGBD Oracle Express 11g wersja 2 (punkt 23.6);
- SGBD IBM DB2 Express-C 10.5 (punkt 23.8);
- SGBD Firebird 2.5.4 (punkt 23.10);
- klienci EMS Manager swoich sześciu SGBD (punkt 23.5);
Uwaga na wersję 1.8. W jednym z przykładów wykorzystano metodę z pakietu Java 8.
Większość przykładów to projekty Maven, które można otwierać zarówno w IDE Eclipse, IntellijIDEA, jak i w NetBeans. Poniższe zrzuty ekranu pochodzą z IDE Spring Tool Suite, odmiany środowiska Eclipse.
1.4. Przykłady
Przykłady są dostępne pod adresem URL [http://tahe.developpez.com/java/spring-database] w postaci pliku zip do pobrania.
![]() |
- w [1] znajdują się foldery z przykładami;
- w pliku [2], folder [spring-core] zawiera projekty szkoleniowe dotyczące Springa;
- w pliku [3], folder [spring-database-config] zawiera projekty konfiguracyjne JDBC i JPA dla sześciu baz danych;
![]() |
- w [4] znajduje się konfiguracja Oracle z pliku SGBD. Znajdują się w nim trzy foldery:
- [databases] zawiera skrypty SQL służące do generowania dwóch baz danych wykorzystywanych przez dokument;
- [jdbc-driver] zawiera sterownik Oracle o nazwie JDBC oraz skrypt instalujący go w lokalnym repozytorium Maven;
- [eclipse] zawiera [5] cztery projekty konfiguracyjne Oracle:
- [oracle-config-jdbc] konfiguruje warstwę JDBC dostępu do SGBD;
- [oracle-config-jpa-hibernate] konfiguruje warstwę JPA zapewniającą dostęp do SGBD przy użyciu dostawcy JPA Hibernate;
- [oracle-config-jpa-eclipselink] konfiguruje warstwę JPA zapewniającą dostęp do SGBD przy użyciu dostawcy JPA Eclipselink;
- [oracle-config-jpa-openjpa] konfiguruje warstwę JPA dostępu do SGBD przy użyciu dostawcy JPA OpenJPA;
- w [6] folder [eclipse config / launch configurations] zawiera konfiguracje uruchomieniowe, które użytkownik będzie mógł zaimportować do Eclipse, a następnie dostosować do własnego środowiska;
![]() |
- w pliku [7], folder [spring-database-generic] zawiera cały kod dostępu do SGBD, wspólny dla sześciu plików SGBD oraz trzech dostawców JPA;
- w [8], [spring-jdbc] zawiera cztery projekty, które obejmują API, JDBC oraz Spring JDBC;
- w [9], [spring-jpa / spring-jpa-generic] to projekt wykorzystujący warstwę JPA w celu uzyskania dostępu do bazy danych. Projekty [generic-create-db*] to projekty JPA umożliwiające tworzenie baz danych wykorzystywanych przez warstwę JPA;
![]() |
-
w [10] folder [spring-webjson] zawiera projekty udostępniające bazę danych w sieci;
- [spring-webjson-server-jdbc-generic] to usługa internetowa udostępniająca bazę danych, do której dostęp zapewnia Spring JDBC;
- [spring-webjson-server-jpa-generic] to usługa internetowa udostępniająca bazę danych, do której dostęp zapewnia Spring JPA;
- [spring-webjson-client-generic] to jedyny klient umożliwiający dostęp do obu powyższych usług internetowych;
-
w [11] folder [spring-security] zawiera projekty, które udostępniają bazę danych w sieci za pomocą bezpiecznego dostępu;
- [spring-security-server-jdbc-generic] to zabezpieczona usługa internetowa, która udostępnia bazę danych, do której dostęp zapewnia Spring JDBC;
- [spring-security-server-jpa-generic] to zabezpieczona usługa internetowa udostępniająca bazę danych, do której dostęp zapewnia Spring JPA;
- [spring-security-client-generic] to jedyny klient umożliwiający dostęp do obu powyższych zabezpieczonych usług internetowych;
-
w [12] folder [spring-cors] zawiera projekty, które udostępniają bazę danych w sieci za pomocą bezpiecznego dostępu, umożliwiającego dostęp międzydomenowy, np. z kodu JavaScript przeglądarki;
- [spring-cors-server-jdbc-generic] to zabezpieczona usługa internetowa umożliwiająca dostęp międzydomenowy i udostępniająca bazę danych, do której dostęp zapewnia Spring JDBC;
- [spring-cors-server-jpa-generic] to zabezpieczona usługa internetowa umożliwiająca dostęp międzydomenowy, udostępniająca bazę danych, do której dostęp zapewnia Spring JPA;
- [spring-cors-client-generic] to aplikacja internetowa umożliwiająca wysyłanie zapytań do obu powyższych usług internetowych;












