www.eprace.edu.pl » obiektowe-bazy » Standardy » Java Data Objects

Java Data Objects

JDO (Java Data Objects) to nowy standard, który został stworzony przez firmę Sun Microsystems. Standard ten ma na celu zdefiniowanie sposobu łączenia aplikacji napisanych w języku Java z obiektowymi bazami danych. JDO jest na razie bardzo „świeżą” specyfikacją, co powoduje, że nie można znaleźć działających zgodnie z nią systemów. Mając jednakże na uwadze, że to właśnie firma Sun Microsystems jest twórcą Javy, można się spodziewać, że standard ten szeroko się rozpowszechni.

Informacje przedstawione w kolejnych podrozdziałach zostały wybrane z opracowań [Bobzin 2000, Criag 2001, Criag 2002, Echelpoel 2002, Jordan 2000,
Jordan 2001, OpenFusion 2002].

Rozwój standardu

Zanim powstało JDO, Sun Microsystems stworzył dwie metody umożliwiające przechowywanie danych. Pierwszą jest JDBC11, drugą zaś serializacja obiektów. Jako że JDBC jest adresowane do tych, którzy chcą korzystać z relacyjnych baz danych, a

serializacja dla tych, którzy chcą przesyłać obiekty, JDO nie jest metodą, która miałaby z nimi konkurować. JDO ma je uzupełniać, lub nawet rozszerzać ich możliwości. JDO może być samodzielnym interfejsem języka Java do obiektowych baz danych, może także być zaimplementowane ponad warstwą JDBC i emulować cechy obiektowe w relacyjnych bazach danych.

Pierwsze plany stworzenia nowej specyfikacji pojawiły się na początku 1999 roku. W sierpniu 1999 uformowała się pod kierownictwem Criaga Russel’a grupa robocza mająca prowadzić prace nad JDO. W maju 2000 roku ukazał się dokument zawierający ogólny zarys koncepcji JDO, natomiast w maju kolejnego roku wydana została w dokumencie [Criag 2001] proponowana specyfikacja JDO. 25 marca 2002 roku koncepcja ta z małymi zmianami stała się oficjalnym standardem [Criag 2002] firmy Sun Microsystems dotyczącym łączenia aplikacji Javy z obiektowymi bazami danych.

Główne cele, jakie przyświecały twórcom JDO to:

Architektura JDO

Schemat bazy danych

Aby system zarządzania obiektową bazą danych mógł przechowywać dane, musi znać strukturę samej bazy danych. Struktura bazy danych to nic innego, jak struktura klas w programie. Struktura ta określana jest mianem metadane (ang. metadata). Owe metadane zapisywane są w plikach formatu XML. Każda klasa zdolna do trwałości, posiada swój własny plik o nazwie „<nazwa-klasy>.jdo”.

Metadane, oprócz serwera baz danych, wykorzystywane są także przez JDO Enhancer do modyfikacji B-kodu plików „class”.

Obowiązek tworzenie plików ze schematem bazy danych spoczywa bądź to na programiście, bądź na dodatkowych narzędziach, potrafiących wygenerować metadane z deklaracji klas zawartych w kodzie źródłowym aplikacji.

Poniżej przedstawiono przykład pliku zawierającego metadane dla klasy Employee.

Deklaracja klasy:

package com.xyz.hr;

class Employee {

String name;

Float salary;

Department dept;

Employee boss;

}

Zawartość pliku:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE jdo SYSTEM "jdo.dtd">

<jdo>

<package name="com.xyz.hr">

<class name="Employee" identity-type="application" objectid-class= "EmployeeKey">

<field name="name" primary-key="true">

<extension vendor-name="sunw" key="index" value="btree"/>

</field>

<field name="salary" default-fetch-group="true"/>

<field name="dept">

<extension vendor-name="sunw" key="inverse" value="emps"/>

</field>

<field name="boss"/>

</class>

</package>

</jdo>

Trwałe obiekty w Javie - interfejs PersistenceCapable.

Jednym z problemów postawionych przed grupą tworzącą standard JDO była potrzeba umożliwienia istnienia obiektów, które nie są już osiągalne przez wskazania z żadnej innej klasy, czyli tzw. trwałych obiektów (ang. persistent objects). Normalnie, obiekty takie są niszczone przez odśmiecacz pamięci (ang. garbage collector) w wirtualnej maszynie Javy. Istnienie obiektów zdolnych do trwałości osiągnięto na dwa sposoby. Pierwszym sposobem jest dodanie przez programistę do odpowiednich klas interfejsu PersistenceCapable. Drugim jest modyfikacja B-kodu Javy przez specjalne narzędzie zwane JDO Enhancer. Stosowanie takiego rozwiązania nie wymaga ingerencji programisty, ponieważ obiekty większości standardowo zadeklarowanych klas, mogą być zamienione na trwałe przez JDO Enhancer. W bazie danych mogą być umieszczane tylko klasy zdolne do trwałości.

Według modelu obiektu JDO, klasy można podzielić na dwa rodzaje: takie, które implementują interfejs PersistenceCapable oraz takie, które go nie implementują. Pierwszym rodzajem nie mogą być klasy, których stan zależy od innych odległych obiektów, czyli na przykład takich, które dziedziczą po java.net.SocketImpl lub implementują interfejs java.net.SocketOptions.

Klasy, które implementują interfejs PersistenceCapable można z kolei podzielić na dwie grupy. Pierwsza grupa obejmuje klasy, których instancje posiadają swój unikalny identyfikator zwany JDO Identity. Takie obiekty nazywają się First Class Object. Druga grupa zawiera klasy, których instancje nie posiadają owego identyfikatora, ich obiekty nazywają się Second Class Object. Obiekty klasy typu FCO można bez problemów przechowywać w bazie, a później je pobrać, zadając serwerowi zapytania. Instancje klasy typu SCO nie mogą samodzielnie istnieć w bazie, jednakże mogą się tam znajdować jako części składowe obiektu FCO.

Obiekty klas zdolnych do trwałości w czasie swojego życia, można scharakteryzować za pomocą następujących cech określających ich stan:

Modyfikator kodu binarnego JDO Enhancer.

Jak już wcześniej wspomniano, trwałe klasy można deklarować w kodzie programu. Można również używać narzędzia zwanego JDO Enhancer, aby uczynić dane klasy klasami trwałymi. JDO Enhancer na podstawie metadanych z odpowiednich plików „jdo” modyfikuje kod binarny zawarty w plikach „class”. Głównym jego zadaniem jest przekształcanie klas do postaci trwałych klas. Przekształcenie to polega na zmianie odpowiednich klas tak, aby implementowały interfejs PersistenceCapable oraz na dodaniu kodu związanego z metodami zawartymi w tym interfejsie. Dodatkowo narzędzie to może dokonywać innych koniecznych modyfikacji. Przykładem takiej modyfikacji może być dodanie do klasy atrybutu typu Integer, który będzie wykorzystywany przez bazę jako klucz główny. Enhancer będzie ignorował klasy, które zostały obdarzone przez programistę interfejsem PersistenceCapable. Enhancer nie będzie związany z konkretnym serwerem bazodanowym. Jest to zgodne z głównym założeniem języka Java, czyli przenośnością kodu binarnego. Powoduje to, iż zmodyfikowane pliki „class” będą mogły komunikować się z dowolną obiektową bazą danych, zgodną ze specyfikacją JDO. Aby zmienić serwer na inny, nie będzie potrzeby modyfikowania plików „class” odpowiednio innym Enhancer’em.

Poniższy schemat prezentuje kompilację aplikacji korzystającej z JDO z użyciem JDO Enhancer’a (rys. 4.2).


RYSUNEK 4.2. KOMPILACJA APLIKACJI KORZYSTAJĄCEJ Z JDO Z UŻYCIEM JDO ENHANCER’A.

Dostęp do bazy danych - język JDOQL

Java Data Objects zrywa z dotychczasowymi standardami dostępu do baz danych opartych na języku SQL. Twórcy standardu JDO stworzyli interfejsy PersistenceManager oraz Query, za pomocą których można wykonywać operacje, jakie w relacyjnych bazach danych specyfikowało się w języku SQL.

Nowy sposób dostępu do bazy danych nazwano JDOQL (Java Data Objects Query Language).

W przykładach poniższych wykorzystywana będzie definicja następującej klasy Person:

class Person implements PersistenceCapable{

String name;

int age;

public void setName(String name){

this.name=name;

}

public void setAge(int age){

this.age=age;

}

}

Umieszczanie obiektów w bazie danych

Umieszczenie obiektu w bazie danych to nic innego niż spowodowanie, aby stał się on obiektem trwałym. W poniższym przykładzie stworzono instancję klasy Person zawierającą informacje o pewnej osobie (tutaj informacje te to imię i wiek).

fCon.beginTransaction();

Person p = new Person();

fPm.makePersistent(p);

p.setName("John");

p.setAge(20);

fCon.commitTransaction();

Pobieranie obiektów z bazy

Język zapytań JDOQL oparty jest na selekcji według wartości atrybutów obiektów. Warunki zawarte w zapytaniach opierają się na wyrażeniach logicznych, które muszą być spełnione, aby dany obiekt został pobrany z bazy. Nowością jest ustalanie parametrów pobranego zestawu obiektów po zadaniu zapytania. W poniższym przykładzie pobierane są z bazy wszystkie te instancje klasy Person, które reprezentują osoby mające powyżej 10 lat. Dodatkowo zestaw ten zostanie posortowany rosnąco według wieku.

String filter - "age > 10";

Query q = fPM.newQuery(Person.class, filter);

q.setOrdering ("age ascending");

Collection result = (Collection)q.execute();

- Modyfikacja obiektów w bazie

Język JDOQL nie posiada możliwości takich jak słowo kluczowe UPDATE znane z języka SQL. Modyfikacja obiektów w bazie danych odbywa się zawsze w dwóch etapach. Pierwszym jest zadanie zapytania do bazy, aby pobrać interesujący nas zestaw instancji klas. Drugim krokiem jest modyfikacja owego zestawu. W poniższym przykładzie zmieniany jest każdy obiekt, który reprezentuje osobę o liczbie lat równej 20. Po pobraniu takiego zestawu obiektów, drugim krokiem jest ustawienie w nich liczby lat na 21.

fCon.beginTransaction();

String filter - "age == 20";

Query q = fPM.newQuery(Person.class, filter);

Collection result = (Collection)q.execute();

Iterator iter = result.iterator();

while(iter.hasNext()){

Person p = (Person)iter.next();

p.setAge(21);

}

fCon.commitTransaction();

Kasowanie obiektów z bazy

Podobnie jak modyfikacje danych, kasowanie danych również przebiega dwuetapowo. Kasowanie obiektów wykonuje się w sposób nietypowy dla Javy, a mianowicie poprzez wywołanie funkcji kasującej. Skasowany obiekt zostaje usunięty z bazy, jak również z pamięci operacyjnej. Usuwanie z pamięci operacyjnej następuje w sposób analogiczny do zwykłych klas w Javie. W poniższym przykładzie kasowane są wszystkie obiekty typu Person, które odpowiadają osobom niepełnoletnim (o liczbie lat mniejszej niż 18).

fCon.beginTransaction();

String filter - "age < 18";

Query q = fPM.newQuery(Person.class, filter);

Collection result = (Collection)q.execute();

Iterator iter = result.iterator();

while(iter.hasNext()){

Person p = (Person)iter.next();

fPm.deletePersistent(p);

p = null;

}

fCon.commitTransaction();

Java Data Objects a Enterprise Java Beans

Istnieją dwa typy ziaren EJB (Enterprise Java Beans): Entity Beans oraz Session Beans. Ze względu na specyfikę komponentów, sposoby przechowywania każdego z tych typów w bazie za pomocą JDO różnią się od siebie.

Ziarna typu Entity Beans

Entity Beans to komponenty, które mogą być używane w tym samym czasie przez wielu klientów. Serwer aplikacji zgodny ze specyfikacją j2ee (Java 2 Enterprise Edition) dostarcza dwie metody, które zapewniają trwałość ziaren EJB. Metody te nazywane są: BMP (Bean Managed Persistence) i CMP (Container Managed Persistence). Te dwie metody nie pozwalają niestety na uzyskanie pełnej funkcjonalności płynącej z JDO. Sugerowanym sposobem na umożliwienie stosowania trwałości komponentów Entity Beans zgodnym z JDO jest stworzenie dostępu do nich zgodnie ze specyfikacją DAO (Data Access Object). Trwałość komponentów można zaszyć w implementacji DAO. Konsekwentne odwoływanie się do Entity Beans za pomocą DAO pozwoli uzyskać żądany efekt, czyli możliwość umieszczania Entity Beans w obiektowych bazach danych.

Ziarna typu Session Beans

Session Beans to komponenty, których instancje tworzą się niezależnie dla każdego klienta z osobna. Aby osiągnąć trwałość tych komponentów wymaganą przez JDO, należy skojarzyć każdy z nich z instancją klasy PersistenceManagerFactory, która pochodzi z JDO. Jedna instancja PersistenceManagerFactory powinna być dzielona przez wszystkie ziarna korzystające z jednej bazy danych. Każda metoda znajdująca się w owych ziarnach powinna otrzymać dostęp do instancji PersistenceManager pochodzącej z PersistenceManagerFactory.



komentarze

Copyright © 2008-2010 EPrace oraz autorzy prac.