-
Notifications
You must be signed in to change notification settings - Fork 2
Instrukcja
Czyli jak OneWeb SQL przyspiesza programowanie przy wciąż zmieniającym się schemacie bazy danych
Zainstaluj na swoim komputerze następujące programy.
- Java 1.6 lub wyższa. Ustaw zmienną
JAVA_HOME
odpowiednio. - PowerDesigner 16. Wersję ewaluacyjną można pobrać ze strony http://response.sybase.com/forms/PDV16-EA
- Eclipse (http://www.eclipse.org/downloads/)
- PostgreSQL 9.1 (http://www.enterprisedb.com/products-services-training/pgdownload). Razem z PostgreSQL instaluje się program pgAdmin. Jako locale wybierz ’Polish’.
- Tomcat 7.0 (http://tomcat.apache.org/download-70.cgi)
- OneWebSQL PD2Java 1.0.0 (http://OneWebSQL.com/download)
W instrukcjach dla użytkowników używamy następujących skrótów.
-
<PROJECT>
– główny katalog aplikacji demo -
<ONEWEBSQL HOME>
– katalog, w którym jest zainstalowany OneWebSQL -
<TOMCAT HOME>
– katalog, w którym jest zainstalowany serwer Tomcat
- Rozpakuj plik ZIP z aplikacją demo.
- Skonfiguruj projekt. Utwórz nowy projekt w Eclipse’ie File > New > Java Project ... i podaj lokalizację źródeł.
Sprawdź, że katalogisrc
,generated-sources
są folderami źródłowymi (Source Folders). Załóż katalogWEB-INF\classes
i ustaw go jako folder docelowy (Output Folder). - Skopiuj plik
<ONEWEBSQL HOME>\onewebsql-runtime-1.0.0.jar
do katalogu<PROJECT>\WEB-INF\lib
. Skopiowany plik dodaj do Build Path. - Do Build Path dodaj ścieżkę do pliku
<TOMCAT HOME>\lib\servlet-api.jar
. - Przygotuj bazę danych. Uruchom program pgAdmin (został zainstalowany razem z PostgreSQL-em). Uruchom konsolę SQL.
- (a) Stwórz użytkownika ’onewebsql’ z hasłem ’onewebsql’.
create user onewebsql password ’onewebsql’;
- (b) W ten sam sposób załóż bazę ’onewebsql’.
create database onewebsql owner onewebsql;
- (c) Połącz się z bazą danych jako użytkownik onewebsql.
- Uruchom skrypt zakładający tabele (
<PROJECT>\database\create-schema.sql
), wstaw dane początkowe (skrypt<PROJECT>\database\initial-data.sql
). - Skonfiguruj serwer Tomcat.
- (a) kopiuj plik
<PROJECT>\lib\postgresql-9.1-902.jdbc3.jar
do<TOMCAT HOME>\lib
. - (b) Do katalogu
<TOMCAT HOME>\conf\Catalina\localhost
skopiuj plik<PROJECT>\META-INF\context.xml
. Zmień jego nazwę naonewebsql.xml
. - (c) W pliku
onewebsql.xml
w atrybuciedocBase
podaj ścieżkę do projektu w Eclipse’ie.
- Uruchom serwer Tomcat: plik
<TOMCAT HOME>\bin\startup.bat
. - W przeglądarce otwórz stronę http://localhost:8080/onewebsql.
Będziemy pracować w prostej aplikacji WWW. Uruchom program PowerDesigner i otwórz plik
<PROJECT>\database\Bookshop.pdm
. Plik zawiera początkowy schemat bazy danych.
Dla każdej tabeli OneWebSQL generuje 3 pliki Javy:
- prostego beana reprezentującego wiersze tabeli,
- interfejs DAO, dający dostęp do tabeli,
- implementację DAO.
Jak to w życiu bywa, schemat bazy danych będzie się zmieniał. Dlatego każde ćwiczenie rozwiązuj w osobnej metodzie. Wtedy zobaczysz, w jaki sposób OneWebSQL pomaga poprawić kod aplikacji po zmianie schematu bazy danych.
Użyjemy OneWebSQL-a w wersji standalone (jest też plugin do Maven 2). W Eclipse’ie wybierz Run > External Tools > External Tools Configurations... Utwórz nową konfigurację typu Program.
- Podaj javę jako program do uruchomienia.
- Jako katalog uruchomienia podaj swój projekt w Eclipse’ie.
- Podaj argumenty generatora:
java -jar <ONEWEBSQL_HOME>\onewebsql-pd2java-1.0.0.jar
-classpath <ONEWEBSQL_HOME>\onewebsql-runtime-1.0.0.jar
-model_sets database\Bookshop.pdm
-java_output_dir generated-sources
-java_default_package com.onewebsql.demo.or
-dictionaries_dir database
- Zapisz konfigurację pod nazwą OneWebSQL. Uruchom generację.
- Odśwież projekt w Eclipse’ie.
- Obejrzyj kod klasy DemoServlet. Klasa zawiera szkielet aplikacji WWW. Główną metodą jest metoda doGet.
- Wypisz listę wszystkich książek. W metodzie doGet odkomentuj wywołanie metody
exercise1
. Przeczytaj kod metodyexercise1
. Do wypisania listy książek użyto metodygetBookList()
w interfejsieBookDAO
. - Uporządkuj wypisywaną listę książek według tytułu
- (a) rosnąco,
- (b) malejąco.
- Wykorzystaj metody z interfejsu
BookDAO
:getBookList(AExp orderByColumn)
oraz `getBookList(AExp OrderByColumn, boolean ascending). Jako orderByColumn podaj stałą
BookDAO.TITLE``. - Wypisz listę książek o id większym od 2. Użyj metody
getBookList(LExp whereClause)
z interfejsuBookDAO
. Warunek where powinien mieć postaćBookDAO.NAZWA KOLUMNY.gt(2)
. - Wypisz listę książek, których tytuły zaczynają się na literę A. Podpowiedź: użyj metody
like
.
- Nie wszystkie zapytania można wygenerować za pomocą metod get*List() z klas typu DAO. Istnieje również obiektowy język zapytań, w którym zapytania SQL można tworzyć bezpośrednio. Zapytanie jest reprezentowane przez obiekt klasy SelectQuery. Obiekt tego typu można podać, np. do metody getBookList(SelectQuery query) w interfejsie BookDAO. Poniższy diagram pokazuje, które klasy odpowiadają różnym częściom zapytania SQL.
- Wypisz listę wszystkich książek używając obiektowego języka zapytań. Zapytanie, które pobiera dane z tabeli book tworzymy za pomocą
new SelectQuery(BookDAO.TABLE EXPRESSION)`. Zapytanie wykonujemy metodą
getBookList(SelectQuery)w interfejsie
BookDAO.
SelectQuery query = new SelectQuery(BookDAO.TABLE_EXPRESSION);bookDAO.getBookList(query);`` - Powtórz poprzednie zapytania, używając obiektowego języka zapytań:
- (a) Wypisz listę książek, których tytuły zaczynają się na literę A.
- (b) Wypisz listę książek, które wydano po 2005 roku.
- (c) Uporządkuj listę książek według roku wydania. Wykorzystaj metodę
orderBy
w klasieSelectQuery
.
- Wypisz listę pierwszych 2 książek o ponad 100 stronach, w porządku alfabetycznym według tytułów. Wykorzystaj metodę
limit(int)
w klasieSelectQuery
.
Wszyscy wiemy, że zmiany schematu bazy danych są nieuniknione. Tym razem zmiana jest prosta: kolumna number of pages nie będzie nam potrzebna i chcemy ją usunąć. Na tym przykładzie pokażemy, jak wygląda proces dewelopmentu aplikacji z OneWebSQL-em.
- Zmień schemat bazy danych. W schemacie bazy danych w PowerDesignerze (plik \database\Bookshop.pdm) w ta- beli book usuń kolumnę number of pages. Zapisz zmiany w PowerDesignerze.
- Wygeneruj skrypt SQL. Wygeneruj skrypt zakładający bazę danych (Database > Generate Database...).
-
Wprowadź zmiany w bazie danych.
- (a) W programie pgAdmin usuń wszystkie tabele w bazie onewebsql. Kliknij prawym klawiszem myszy na tabeli i wybierz Drop Cascaded.... Powtórz czynność dla sekwencji (węzeł Sequences).
- (b) Uruchom wygenerowany przez PowerDesignera skrypt zakładający bazę danych. Kliknij ikonę Wykonaj dowolne zapytanie SQL. Wskaż lokalizację skryptu, a następnie kliknij przycisk Wykonaj zapytanie.
- (c) Wstaw dane początkowe. Możesz użyć przygotowanego skryptu
<PROJECT>\database\initial-data-without-number-of-pages.sql.
- Wygeneruj klasy OneWebSQL-a. Uruchom generator, który skonfigurowaliśmy w części 2. Odśwież projekt w Eclipse’ie.
-
Popraw kod aplikacji.
Zauważ, że niekompatybilne zmiany są sygnalizowane w postaci błędów kompilacji. Nie musisz zastanawiać się, co trzeba poprawić. Popraw kilka metod, pozostałe możesz usunąć lub zakomentować.
- Wypisz listę książek, które należą do kategorii, których nazwa zaczyna się na literę P. Potrzebne zapytanie wykorzystuje dwie tabele: book i category. Możesz użyć:
- (a) konstruktora klasy SelectQuery, który bierze listę tabel. Podaj odpowiedni warunek złączenia w metodzie
where
. - (b) konstruktora klasy
SelectQuery
, który bierze obiekt typucom.onewebsql.query.Join
. Użyj odpowiedniej metody statycznej z klasyJoin
.
- Wypisz listę książek i nazwę kategorii, do której dana książka należy. Rekomendowany sposób to utworzenie odpowiedniego widoku i wygenerowanie dla niego klas OneWebSQL-a.
- (a) W PowerDesignerze w panelu Toolbox wybierz ikonę View z sekcji Physical Diagram i kliknij w diagram. Zakończ dodawanie widoku klikając w prawy przycisk.
- (b) Zmień nazwę widoku. Kliknij dwukrotnie na ikonę widoku. W oknie dialogowym wpisz nazwę:
book_with_category_view
. - (c) W zakładkę SQL Query wpisz treść zapytania SQL:
SELECT
book.book_id,
book.category_code,
category.category_name,
book.title,
book.publication_year
FROM
book JOIN category ON book.category_code = category.category_code;
- Wciśnij OK a następnie zapisz model PowerDesignera.
W PowerDesignerze wygeneruj skrypt zakładający bazę danych. Skasuj tabele i sekwencje z bazy danych analogicznie jak w części 5. Następnie uruchom wygenerowany skrypt zakładający bazę danych i skrypt
<PROJECT>\initial-data-book-with-category-view.sql
. Wygeneruj klasy OneWebSQL-a i odśwież projekt w Eclipse’ie. - Tę samą listę można wypisać inaczej, nie tworząc widoku, lecz korzystając z obiektowego języka zapytań.
- (a) Utwórz obiekt SelectQuery reprezentujący zapytanie SQL z punktu 2c.
- (b) Metody klas DAO w rodzaju getBookList(SelectQuery) przekształcają wyniki na obiekty klasy Book. Jeśli chcemy zwrócić obiekt innej klasy, musimy posłużyć się metodą selectObjectList(SelectQuery,RowHandler) i podać jej odpowiedni RowHandler.
public interface RowHandler<T> {
T getObject(ResultSet resultSet) throws SQLException;
}
Obiekty typu com.onewebsql.util.jdbc.RowHandler przekształcają wyniki bazy danych na obiekty Javy.
- (c). Przykładowy kod istniejącego
RowHandlera
.
public class ListRowHandler<T> implements RowHandler<List<T>> {
@SuppressWarnings("unchecked")
public List<T> getObject(ResultSet resultSet) throws SQLException {
int count = resultSet.getMetaData().getColumnCount();
List<T> result = new ArrayList<T>(count);
for (int i = 1; i <= count; i++) {
Object obj = resultSet.getObject(i);
if (resultSet.wasNull()) {
obj = null;
}
result.add((T) obj);
}
return result;
}
}
- (d) Użyj obiektu
ListRowHandler<Object>
, aby pobrać i wypisać wyniki zapytania utworzonego w punkcie 3a.
W obiektowym języku zapytań można tworzyć praktycznie dowolne zapytania SQL. Poniżej kilka przykładów.
- Napisz zapytanie zwracające informacje, w którym roku wydano ile książek. Przykładowe zapytanie SQL, które to robi.
SELECT publication_year, count(*)
FROM book
GROUP BY publication_year;
Kolumnę count(*)
tworzy się tak: AExp.fun("count", AExp.exp("*"))
. Używamy tu statycznej metody com.onewebsql.query.AExp.fun(String,AExp)
. Klauzulę GROUP BY
dodajemy wywołując metodę groupBy na obiekcie SelectQuery
.
- Powtórz poprzednie ćwiczenie dla książek wydanych po roku 2005.
SELECT publication_year, count(*)
FROM book
GROUP BY publication_year;
HAVING publication_year > 2000;
Klauzulę HAVING
dodajemy wywołując metodę having na obiekcie SelectQuery
.
- Znajdź autora, który napisał najwięcej książek. Przykładowe zapytanie SQL, które to robi:
SELECT author.name
FROM author, book_author
WHERE author.author_id=book_author.author_id
GROUP BY author.author_id, author.name
HAVING count(*) >= ALL(
SELECT count(*)
FROM author,book_author
WHERE author.author_id = book_author.author_id
GROUP by author.author_id);
- Wylosuj dwie książki z listy wszystkich książek znajdujących się w bazie danych. Można to zrobić pobierając listę wszystkich książek z bazy danych. To rozwiązanie jest mało efektywne, jeśli danych w bazie jest dużo. Dlatego zrobimy to inaczej.
Najpierw pobierz z bazy listę identyfikatorów książek. Posłuż się metodą selectObjectList z
klasy
BookDAO
, jakoRowHandler
daj obiekt klasySingleColumnRowHandler<Integer>
. Z otrzymanej listy wylosuj dwa identyfikatory. Pobierz wylosowane książki posługując się wylosowanymi identyfikatorami.
- Oprogramuj dodawanie nowego autora. Wstaw do metody
doGet
wywołanie metodydispatchRequest
, usuń wywołania metod napisanych w poprzednich ćwiczeniach. Na głównej stronie aplikacji pojawi się formularz dodawania autora oraz lista autorów.Obsługą formularza zajmuje się metoda
addAuthor()
. Wypełnij jej treść. Do wstawiania nowych obiektów służy metodainsert(Author)
w interfejsieAuthorDAO
. Aby odczytać wartość pola name w formularzu, wywołaj metodęgetParameter("name")
na obiekcieHttpServletRequest
. - Oprogramuj edycję danych autora. Formularz edycji jest już przygotowany. Aby się do niego dostać, kliknij Edit na liście autorów. Obsługą formularza zajmuje się metoda saveAuthor. Najpierw pobierz obiekt autora za pomocą metody
getByPK(Integer id)
w interfejsieAuthorDAO
. Wprowadź zmiany w obiekcie, a następnie zapisz zmiany w bazie danych za pomocą metodyupdate(Author)
. - Oprogramuj usuwanie autora z bazy danych, tę operację obsługuje metoda
deleteAuthor
. Do usuwania obiektów w bazie danych służy metodadelete(Author)
z interfejsuAuthorDAO
. Pamiętaj także o usunięciu powiązań autora z książkami.
- Zmień tabelę category na słownik. W katalogu
<PROJECT>\database
utwórz plik o nazwiecategory.csv
o takiej strukturze:
category_code;code;category_name
prog;prog;Programming
dev;dev;Software Development
Wygeneruj klasy OneWebSQL-a i schemat bazy danych. Zauważ, że powstała nowa klasa CategoryDICT. Obejrzyj jej zawartość.
- Wypisz listę książek, które należą do kategorii prog. Użyj stałej słownikowej w warunku where.
- Przygotuj formularz edycji książki, w którym kategorię książki można wybrać z listy rozwijanej, wypełnionej istniejącymi kategoriami. Zauważ, nie musisz pobierać listy kategorii z bazy danych.
com.onewebsql.util.jdbc.RuntimeSQLException: SQLSTATE: 42501;
ERROR CODE: 0; org.postgresql.util.PSQLException:
Uruchomiliśmy skrypty z root-a bazy danych (postgres
), a nie z użytkownika onewebsql
.