Bazy danych i inżynieria oprogramowania

Download Report

Transcript Bazy danych i inżynieria oprogramowania

Bazy danych i inżynieria oprogramowania
Wykład 13:
Wprowadzenie do
standardu ODMG, część 7:
Wiązanie do Java
Kazimierz Subieta
Instytut Podstaw Informatyki PAN,
Warszawa
Polsko-Japońska Wyższa Szkoła
Technik Komputerowych, Warszawa
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 13, Folia 1
Założenia wiązania do Java
Wiązanie do Java jest oparte na zasadzie zgodnie z którą programista powinien
odbierać całość wiązania jako pojedynczy język dla wyrażania jednocześnie
operacji na bazie danych jak i operacji na ulotnych strukturach języka
programowania. Ta zasada implikuje kilka dalszych konsekwencji:
Programista ma do czynienia z pojedynczym, zunifikowanym systemem
typów zarówno dla obiektów programistycznych (ulotnych) jak i dla obiektów
bazy danych (trwałych).
Wiązanie respektuje składnię języka Java (nie wprowadza dodatkowej
składni).
Wiązanie respektuje semantykę składowania obiektów języka Java, w
szczególności automatyczne zbieranie nieużytków (garbage collection).
Obiekt (trwały lub ulotny), do którego nie można dostać się z poprzez
referencje staje się nieużytkiem. Referencje z trwałych obiektów mogą
prowadzić wyłącznie do trwałych obiektów. Tę własność określa się jako
trwałość poprzez osiągalność (persistence through reachability).
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 13, Folia 2
Sposoby deklarowania klas z obiektami trwałymi
Istniejące klasy języka Java można zdefiniować jako klasy zdolne do
trwałości (persistence-capable).
Klasy zdolne do trwałości mogą mieć zarówno obiekty ulotne jak i trwałe.
Istniejąca wersja standardu nie określa jednak, w jaki sposób można takie
klasy powołać; ta własność jest uważana za cechę implementacyjną.
Deklaracje klas Java (jak również schemat bazy danych) mogą być
automatycznie wygenerowane przez preprocesor ODMG ODL.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 13, Folia 3
Model obiektowy ODMG w Java (1)
Zdaniem autorów standardu ODMG, model obiektowy ODMG i model obiektowy
Java są zbliżone. Niemniej ich różnice powodują, że wiązanie do Java nie
podtrzymuje takich cech modelu obiektowego ODMG jak: związki, ekstensje,
klucze, oraz dostęp do meta-schematu.
Typ obiektu ODMG odwzorowuje się w typ obiektu Java. Podobnie, typy
atomowych literałów ODMG odwzorowują się w równoważne typy prymitywne
Java. Wiązanie nie przewiduje odwzorowania literałów strukturalnych. Definicja
dowolnej struktury w modelu ODMG odwzorowuje się w definicję klasy w Java.
Java przewiduje niezależne definicje interfejsów i implementacji. Interfejsy i klasy
abstrakcyjne nie posiadają wystąpień i z tego powodu nie mogą być klasami
zdolnymi do trwałości.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 13, Folia 4
Model obiektowy ODMG w Java (2)
Kolekcje w ODMG posiadają metody zdefiniowane w ramach interfejsu Collection.
Wiązanie do Java zakłada istnienie następujących interfejsów (i co najmniej jedną
implementację) dla obsługi kolekcji:
public interface Set extends Collection {...}
public interface Bag extends Collection {...}
public interface List extends Collection {...}
Wprowadzony przez ODMG typ kolekcji Array odwzorowuje się w typ prymitywny array w
Java, w klasę Vector, albo w specjalna klasę ODMG VArray, w zależności od potrzeby.
Obiektom bazy danych mogą być przypisane nazwy poprzez zastosowanie metod
zdefiniowanych w klasie Database w Java OML.
Obsługa wyjątków zdefiniowanych w interfejsach ODMG jest określona przez standardowy
mechanizm wyjątków Java. Zdefiniowano szereg specjalnych typów wyjątków. Przykłady
typów wyjątków są następujące: TransactionAbortException (wyjątek powodowany przez
zerwanie transakcji), ObjectNameNotUniqueException (próba nadania dla obiektu nazwy
posiadanej przez inny obiekt), QueryParameterTypeInvalidException (wyjątek powodowany
w sytuacji kiedy typ aktualnego parametru zapytania jest niezgodny z oczekiwanym), i inne.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 13, Folia 5
Java ODL
Język Java ODL (Object Definition Language) służy do zapisu schematu bazy danych
w postaci zbioru klas języka Java (z zachowaniem składni Java). Wystąpienia tych
klas mogą być przetwarzane poprzez zestaw metod określany jako Java OML (Object
Manipulation Language).
Deklaracje atrybutów są identyczne do deklaracji pól w Java. Każdy typ elementarny
z modelu ODMG jest odwzorowany w deklarację typu języka Java zgodnie z tabelą:
Typ z
ODMG
modelu
Long
Short
Unsigned long
Float
String
Date
Set
Array
Iterator
....
Typ języka Java
int(pry mityw), Integer (klasa)
short (prymityw), Short (klasa)
Long (pry mityw), long (klasa)
float (pry mityw), Float (klasa)
String
java.sql.Date
interface Set
array type[] lub Vector
Enu merat ion
....
Czy
może
być
literałem?
tak
tak
tak
tak
tak
nie
nie
nie
nie
....
Standard nie definiuje odwzorowań typu Enum (przeliczeniowego) oraz Interval
(przedział). Deklaracja operacji w Java ODL są identyczne do deklaracji metod w Java.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 13, Folia 6
Java OML (1)
Java OML (Object Manipulation Language) zawiera operacje do tworzenia
obiektów, zmieniania wartości ich pól, oraz ich usuwania i identyfikacji. Daje też
możliwość wywoływania metod. Przyjmuje się jako zasadę, że nie ma różnic w
stosowaniu tych operacji do trwałych i ulotnych obiektów. Ponadto, pojedyncze
wyrażenie może kombinować referencje do trwałych i ulotnych obiektów.
ODMG wprowadza odstępstwa od zasady trwałości poprzez osiągalność. Wystąpienia klas,
które nie są zdolne do trwałości, nigdy nie są trwałe, nawet jeżeli prowadzi do nich referencja
z trwałego obiektu. W ramach trwałego obiektu można utworzyć nietrwały atrybut. Np.klasa
Osoba może mieć nietrwały atrybut referencyjny bieżąceUwagi:
public class Osoba {
public String nazwisko;
transient TypPewnegoObiektuUlotnego bieżąceUwagi;
...}
Atrybut bieżąceUwagi nie będzie zapamiętywany w bazie danych.
Podane reguły dotyczące trwałości są odbierane jako niekonsekwencja standardu lub plątanina
pojęć.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 13, Folia 7
Java OML (2)
Wiązanie do Java nie zakłada istnienia operacji usuwania obiektów. Obiekt przestaje
istnieć w momencie, gdy nie posiada nazwy i nie prowadzi do niego żadna referencja z
(osiągalnego) trwałego obiektu. Nieosiągalny obiekt jest automatycznie usuwany.
Modyfikacje obiektów są widoczne w bazie danych dopiero po potwierdzeniu transakcji,
w ramach której te modyfikacje się odbywają.
Programy aplikacyjne używają nazw obiektów celem odwołania się do tzw. obiektówkorzeni (root objects), od których można rozpocząć nawigację w „pajęczynie” obiektów
składających się na obiektową bazę danych. Nazwy obiektów bazy danych tworzą
pojedynczą, płaską przestrzeń. Wszystkie nazwy w bazie danych są unikalne. Nazwa
obiektu nie jest dostępna jako jego atrybut.
Standard nie mówi nic o tym, czy atrybuty i związki również posiadają nazwy. W
odróżnieniu od nazw obiektów, nazwy te są traktowane (prawdopodobnie) jako byty
drugiej kategorii programistycznej, tj. istnieją wyłącznie w tekście programu.
Atrybuty i związki są dostępne poprzez standardową składnię Java; obydwie kategorie są
odwzorowane w Java jako zmienne polowe (field variables).
Operacje są zdefiniowane w Java OML jako metody w Java. Operacje na obiektach
ulotnych i trwałych zachowują się identycznie i mają identyczną pragmatykę użycia.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 13, Folia 8
Kolekcje
Standard wprowadza interfejsy dla kolekcji: Collection, Set, Bag, List oraz Array.
Obiektowa baza danych powinna definiować dowolną liczbę klas konkretnych
implementujących różnorodne interfejsy dla kolekcji.
public interface Collection
{
// Operacje modelu ODMG
public int size();
// cardinality()
public boolean IsEmpty();
// is_empty()
public void add( Object obj );
// insert_element(...)
public Object remove( Object obj );
// remove_element(...)
public boolean contains( Object obj );
// contains_element(...)
public Enumeration elements()
// Iterator create_iterator(...)
public Object selectElement( String predicate );
public Enumeration select( String predicate );
public Collection query( String predicate );
public boolean existsElement( String predicate );
}
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 13, Folia 9
Kolekcja Set
public interface Set extends Collection
{
public Set union( Set otherSet );
public Set intersection( Set otherSet );
public Set difference( Set otherSet );
public boolean subsetOf( Set otherSet );
public boolean properSubsetOf( Set otherSet );
public boolean supersetOf( Set otherSet );
public boolean properSupersetOf( Set otherSet );
}
// Operacje modelu ODMG
// create_union(...)
// create_intersection(...)
// create_difference(...)
// is_subset_of(...)
// is_proper_subset_of(...)
// is_superset_of(...)
// is_proper_superset_of(...)
Problem z kolekcjami polega na tym, że są one szablonami zawierającymi parametr.
Nie jest pewne, czy mają one być pierwszej czy drugiej kategorii programistyznej.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 13, Folia 10
Transakcje
Transakcje są zaimplementowane w Java OML jako obiekty klasy Transaction, zawierającej
definicję takich metod jak:
• Transaction (utworzenie nowej transakcji),
• join (połączenie aktualnie wykonywanego wątku z pewną transakcją),
• leave (odłączenie wykonywanego wątku od transakcji),
• current (sprawdzenie, do której transakcji jest podłączony wykonywany wątek),
• begin (uruchomienie transakcji; transakcje nie mogą być zagnieżdżane),
• isOpen (sprawdzenie, czy transakcja jest uruchomiona),
• commit (potwierdzenie transakcji),
• abort (zerwanie transakcji),
• checkpoint (potwierdzenie transakcji bez jej zakończenia i z zachowaniem zamków),
• lock (podwyższenie statusu zamka założonego na dany obiekt przez transakcję)
Zanim nastąpią operacje na bazie danych, dany wątek musi utworzyć transakcję lub połączyć
się z istniejącą transakcją przy pomocy operacji join.
Transakcja musi być następnie otwarta poprzez operację begin.
Dalsze operacje danego wątku są wykonywane w ramach tej transakcji, aż do jej zakończenia
lub zerwania. Dany wątek po otwarciu jednej transakcji nie może odwoływać się do żadnej
innej transakcji. W obecnym standardzie transakcje nie dotyczą obiektów ulotnych.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 13, Folia 11
Java OQL (1)
Autorzy standardu twierdzą, że wiązanie do Java zapewnia pełna funkcjonalność
OQL. To twierdzenie jest mało wiarygodne ze względu na zasadnicze różnice
koncepcyjne pomiędzy Java i OQL, powodujące ograniczenia i niewygody.
Możliwości przetwarzania zapytań są zawarte w interfejsie Collection. Metody
selectElement, select, query i existsElement posiadają stringowy argument
predicate, który jest zapytaniem w OQL (ściślej, jest określony przez składnię
klauzuli where). Np. metoda query może być użyta w sposób następujący:
SetOfObject fizycy;
fizycy = Studenci.query(
”exists wykl in this.zapisany_na: wykl.nazwa =\”fizyka\” ”);
Z ekstensji Studenci klasy Student wybierany jest podzbiór zgodnie z predykatem
będącym argumentem metody query. Ten podzbiór jest podstawiany na
zadeklarowany obiekt fizycy.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 13, Folia 12
Java OQL (2)
Wiązanie do Java przewiduje specjalną klasę OQLQuery umożliwiającą
programiście utworzenie zapytania, przekazanie parametrów do zapytania,
wykonanie zapytania oraz przetworzenie jego rezultatu:
class OQLQuery{
public OQLQuery(){}
public OQLQuery( String query ){ ... }
public create( String query ) { ... }
public bind( Object parameter ) { ... }
public Object execute() throws ODMGException { ... }
}
Parametry zapytań musza być obiektami w sensie obiektów Java (np. Integer zamiast int).
Wynik zapytania powinien być także zadeklarowany jako obiekt.
Formalne parametry w zapytaniach są zaznaczone znakiem $i, gdzie i jest numerem
parametru.
Parametry aktualne są dostarczane poprzez zastosowanie metody bind; i-ty parametr jest
ustalany w i-tym wołaniu metody bind. Wołania tej metody powinny poprzedzić wywołanie
metody execute, która dokonuje ewaluacji zapytania.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 13, Folia 13
Przykład Java OQL
Spośród studentów uczęszczających na przedmiot ”fizyka” należy wybrać Studentów_asystentów,
których zarobek jest większy niż 1500, następnie ustalić ich profesorów:
Bag fizycy;
// Obiekt ulotny do przechowania wybranych studentów
Bag profesorowieFizyków; // Obiekt ulotny do przechowania wyniku
Double zarobekJakoObiekt;
OQLQuery mojeZapytanie; // Deklaracja obiektu do przechowania zapytania
fizycy = Studenci.query(
”exists wykl in this.zapisany_na: wykl.nazwa =\”fizyka\” ”);
mojeZapytanie = new OQLQuery(
”select a.asystuje_w.prowadzony_przez
from Student_asystent as a
where a.zarobek > $1 and a in $2” );
zarobekJakoObiekt = new Double(1500.0);
mojeZapytanie.bind( zarobekJakoObiekt );
mojeZapytanie.bind( fizycy );
profesorowieFizyków = (Bag) mojeZapytanie.execute();
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 13, Folia 14
Brak niezgodności impedancji?
Patrząc na kod z poprzedniego slajdu, twierdzenie twórców standardu, że unikają oni
niezgodności impedancji są niewiarygodne.
Rozwiązanie jest nawet bardziej skomplikowane, niż analogiczne rozwiązanie w SQL.
W istocie, w tym kodzie mamy deklaracje trzech procedur funkcyjnych (perspektyw, views).
Np. takie zadanie mogłoby być zapisane w języku opartym na SBQL/Loqis:
procedure fizycy: SetOf Student
begin
return Student where ”fizyka” in (zapisany_na.Wykład.nazwa);
end;
procedure profesorStudAsyst( minZarobek: real;
moiStudenci: SetOf Student): SetOf Profesor
begin
return ((Student_asystent)(moiStudenci where zarobek > minZarobek )) .
asystuje_w.Wykład.prowadzony_przez.Profesor;
end;
procedure profesorowieFizyków: SetOf Profesor
begin
return profesorStudAsyst (1500; fizycy );
end;
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 13, Folia 15
Podsumowanie
ODMG 2.0 ma ambicje być de-facto standardem dla obiektowych baz danych.
Nie jest pewne, czy nie są to ambicje zbyt wygórowane.
• Wiele firm uczestniczy w standardzie i zobowiązało
się go podtrzymywać
• Model obiektowy ODMG jest rozszerzeniem modelu
OMG
• Podstawowe funkcjonalności: ODL, OQL
• Wiązania do C++ i Smalltalk’a, planowane do Java
(niezależnie: Ada)
• Związki z OMG i architekturą CORBA
Co dalej?
W obecnej, już trzeciej wersji standardu, znajduje się wiele rozwiązań
kontrowersyjnych i niejednoznaczności. Można mieć wątpliwości, czy taki
“standard” ma jakikolwiek sens. Należy mieć nadzieję, że ODMG ugnie
się pod cieżarem krytyki i zabierze sie do roboty nad spójną koncepcją,
składnią i semantyką. Jeżeli nie, to twierdzenia o “przenaszalności” można
będzie włożyć między bajki.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 13, Folia 16