Powiązania (referencje) między obiektami



Pobieranie 22,88 Kb.
Data10.02.2018
Rozmiar22,88 Kb.

  1. Powiązania (referencje) między obiektami

  • relacja wiele-do-jednego (plik *.hbm.xml)

  • nazwa_pola” column=”nazwa_kolumny” cascade=”...” />

  • parametry jak property

  • parametr cascade – opisuje operacje na powiązanych obiektach

  • all – zapisuje/update-uje/usuwa obiekt bieżący i te, na które ma referencje

  • save-update – „po referencjach” przenoszą się tylko operacje save i update

  • delete – tylko operacje usuwania

  • none – żadne operacje

  • np. dla kodu:
    Klasa k = new Klasa();
    k.referencja = new Klasa();
    session.Save(k)
    dla cascade=”none” lub „delete” zapisze tylko k (k.referencja musimy zapisać sami)
    w pozostałych przypadkach zapisane zostanie zarówno k jak i k.referencja

  • jeżeli ręcznie tworzymy bazę, należy dodać kolumnę, która będzie przechowywała identyfikator obiektu, na który trzymamy referencję

  • obserwacja leniwego ładowania (show_sql = true)

  • utworzyć obiekt A i B, powiązany z nim (A ma referencję na B)

  • w nowej sesji (np. nowe uruchomienie programu): odczytać z bazy A, wypisać zawartość pól (innych niż referencja)

  • wypisać zawartość pól obiektu, do którego mamy referencję

  • obiekt B zostanie odczytany z bazy dopiero wówczas, gdy będziemy próbowali wypisać jego pola (dopiero przed drugim wypisaniem); do tego czasu B istnieje jako proxy




  1. Kolekcje

  • pola w klasie powinny być typu „interfejsowego” ( IList, ISet, IDictionary, IDictionary<>, itp.)

  • obiekty powinny być utworzone w konstruktorze / jako wartość początkowa

  • private ISet dane = new HashedSet(); public ISet Dane { get {return dane; } set {dane = value; } }

  • public ISet Dane {get; set; } \\ public Klasa() { dane = new HashedSet(); }

  • hibernate podczas zapisywania podmienia zawartość pola na swoją implementację, więc nie będzie poprawne wywołanie: HashedSet s = klasa.Dane;

  • kolekcje poza ISet mają indeks – liczbę typu Int32 lub dowolnego typu (w przypadku słowników)

  • należy to uwzględnić ręcznie tworząc tabele

  • kolekcja przechowywana jest w osobnej tabeli, której kolumny zawierają:

  • daną

  • indeks (poza ISet)

  • identyfikator obiektu, do którego należą

  • węzły map, set, list, array, bag

  • np. dla IDictionary:
    ...
    public IDictionary Dane { get; set; }
    ...
    nazwa_tabeli”>
    kolumna_klucza” />
    klucz” type=”String” />
    dana” type=”Int32” />


  • nazwa_tabeli to nazwa tabeli, w której będą przechowywane dane kolekcji

  • kolumna_klucza to nazwa kolumny w tabeli nazwa_tabeli, przechowującej identyfikator obiektu, do którego wiersz należy

  • klucz to nazwa kolumny w tabeli nazwa_tabeli, przechowującej klucz wartości (dla węzłów innych niż map typ powinien być Int32

  • dana to nazwa kolumny w tabeli nazwa_tabeli, przechowującej daną przypisaną do klucza

  • jeżeli indeks jest obiektem, zamiast węzła index użyć węzła index-many-to-many

  • jeżeli wartość jest obiektem, zamiast węzła element należy użyć węzła many-to-many

  • wykorzystanie w HQL

  • tak opisane kolekcje możemy wykorzystywać w HQL, np. „from Klasa k where k[„klucz”] = 5”



  1. Dziedziczenie

  • sposoby realizacji dziedziczenia

  • model tabela na klasę

  • cała klasa i jej potomne przechowywane są w jednej tabeli

  • klasy rozróżniane są po „discriminator-value”, króra przechowywana jest w osobnej kolumnie

  • kolumny nie mogą mieć ograniczenia not null

  • tabela powinna posiadać kolumny dla wszystkich podklas











...

discriminator-value="CREDIT">

...




discriminator-value="CASH">

...




discriminator-value="CHEQUE">

...







  • model tabela na podklasę

  • pola, o które klasa bazowa jest rozszerzona przechowywane są w osobnej tabeli

  • tabela ta zawiera dodatkowe pole – identyfikator obiektu bazowego

  • obiekt klasy potomnej przechowywany jest częściowo w tabeli bazowej (pola klasy bazowej), a częściowo w dodatkowej tabeli; identyfikator wiąże oba wiersze









...



...






...






...







  • model tabela na konkretną klasę

  • każda klasa posiada swoją tabelę

  • każda tabela musi zawierać wszystkie swoje właściwości

  • kolumny przechowujące pola klasy bazowej muszą nazywać się tak samo we wszystkich tabelach








...


...



...




...







  1. Zapytania w SQL

  • interfejs ISQLQuery

  • ISession::CreateSQLQuery()

  • parametrem jest zapytanie w SQL

  • wynik zapytania należy opisać (przykład 1);

  • ISQLQuery::AddScalar(nazwa, typ)

  • nazwa to alias kolumny wyniku (string)

  • typ to typ wyniku (NHibernateUtil.[String|Int32|itd.])

  • ISQLQuery::List() (nie ma enumerable):

  • IList l = query.List()

  • wynik – lista obiektów (jeżeli pojedyncza kolumna) lub lista tablic obiektów (jak przy zapytaniach HQL)

  • jeżeli chcemy otrzymać obiekty:

  • „SELECT {t.*} from tabela t”

  • tabela – nazwa tabeli, w której przechowywane są obiekty

  • {t.*} oznacza wszystkie pola klasy

  • z indywidualnymi polami jest problem – trzeba odpowiednio aliasować kolumny, tworzyć dodatkowe opisujące typ itp. – spojrzeć na rzeczywiste zapytanie (show_sql = true)

  • obiekty też należy opisać (przykład 2)

  • ISQLQuery::AddEntity(alias_kolumny, typ_obiektu)

  • przykład 3 – odczytanie klasy zawierającej kolekcję

  • trzeba „ręcznie” powiązać dane z tabeli z elementami kolekci

  • przykład 3 nie jest w pełni funkcjonalny – hibernate nie wie, że elementy słownika przeczytał już z bazy danych – przy dostępie do niego wystąpi dodatkowe zapytanie do bazy

  • aby poinformować hibernate o odczytanych danych, trzeba dodatkowo opisać połączenie

  • AddJoin(„nazwa_aliasu_tabeli_kolekcji”, „alias_tabeli_obiektu.nazwa_pola_kolekcji”) (przyład 4)




©operacji.org 2017
wyślij wiadomość

    Strona główna