#13.1 — Baza danych z JPA cz. 1

By 21 November 2014 August 3rd, 2016 Kurs Javy

W dzisiejszej i jutrze­jszej lekcji omówimy pod­stawy JPA — stan­dar­du, który znacznie upraszcza obsługę bazy danych z poziomu aplikacji. W pier­wszej częś­ci lekcji zobaczymy sam JPA, w kole­jnej zaś nauczymy się uży­wać go we włas­nym projekcie.

JPA to stan­dard z grupy tzw. ORM (ang. Object-Rela­tion­al Map­ping), co w wol­nym tłu­macze­niu oznacza mapowanie z mod­elu obiek­towego (takiego, jaki uży­wamy w aplikac­jach Java) do mod­elu rela­cyjnego (takiego, z jakiego korzys­ta­ją bazy danych). Oczy­wiś­cie założe­niem jest, żeby pracę pro­gramisty uproś­cić, a nie utrud­nić, dlat­ego stara­no się zau­tomaty­zować jak najwięcej rzeczy.

Lekcja

Aby korzys­tać z JPA będziemy potrze­bowali tzw. providera — bib­liote­ki, która dostar­cza imple­men­tację stan­dar­du JPA (JPA to tylko zbiór kon­trak­tów, tzn. opisów, jakie funkc­je mają być real­i­zowane i w jaki sposób — sami może­my wybrać lub stworzyć imple­men­tację, która będzie się tym zajmowała)

Tak naprawdę aby korzys­tać z JPA będziemy potrze­bowali jed­nej adno­tacji na każdej klasie oraz jed­nej na jej polu (iden­ty­fika­torze), którą chce­my też prze­chowywać w bazie danych (tak, jed­nej!). Jed­nocześnie może­my (i będziemy) mody­fikować domyślne zachowanie JPA za pomocą dodatkowych adno­tacji aby powiedzieć dokład­nie, co chce­my, i w jaki sposób, żeby było zro­bione. To kole­jny przykład elasty­cznoś­ci i wygody, którą dosta­je­my dzię­ki pode­jś­ciu convention-over-configuration.

Adnotacje w JPA

W przy­pad­ku baz danych (jak pewnie pamięta­cie z ostat­niej lekcji) mówimy o enc­jach i tak najważniejszą adno­tacją w przy­pad­ku JPA jest właśnie @Entity. Adno­tac­ja ta nie wyma­ga żad­nych para­metrów (może­my wybrać nazwę — pewnego rodza­ju alias, uży­wany później w zapy­ta­ni­ach, ale zostaniemy przy domyśl­nym — nazwie klasy), umieszcza­my ją nad całą klasą, która ma być mapowana:

@Entity
public class Kot {
    @Id
    private Long id;

    //...
}

Klasa taka, którą adno­tu­je­my za pomocą @Entity, musi mieć pub­liczne get­tery i set­tery dla każdego pola. Założe­nia przyjęte przez JPA w takiej sytu­acji są następujące:

  • tabela nazy­wa się tak jak klasa
  • kolum­ny nazy­wa­ją się tak, jak pola i są odpowied­niego typu z możli­woś­cią wpisa­nia null

Powyżej widz­imy także adno­tację @Id — wskazu­je nam ona, że dane pole jest iden­ty­fika­torem (unikalnym) tego obiek­tu. Najczęś­ciej jest to pole typu Long o nazwie id lub podob­nej. Bard­zo częs­to moż­na spotkać się z adno­tacją @GeneratedValue, co wskazu­je, że iden­ty­fika­tor ten jest gen­erowany automaty­cznie w momen­cie zapisu do bazy danych.

Zmiana parametrów tabeli

Bard­zo częs­to mamy już gotową bazę danych, którą chce­my zmapować i nie chcąc zmieni­ać jej struk­tu­ry musimy dopa­sować nasze mapowanie (np. nazwę tabeli). Służy do tego adno­tac­ja @Table — najczęś­ciej wyko­rzys­tu­je­my jej para­metr name, jak na poniższym przykładzie:

@Entity
@Table(name="koty")
public class Kot {
    //...
}

Taki zapis spowodu­je, że klasa Kot będzie mapowana na tabelę ‘koty’ zami­ast domyśl­nej tabeli ‘Kot’

Zmiana parametrów kolumny

Podob­nie jak w przy­pad­ku tabeli, domyśl­ną nazwą kolum­ny jest nazwa pola. Najczęś­ciej jed­nak nie jest to zgodne z kon­wencją nazewnict­wa w bazie danych (gdzie częs­to zami­ast camel­Case uży­wamy nazw_z_podkreslnikami). Aby zmienić nazwę kolum­ny lub zmody­fikować jej atry­bu­ty może­my użyć adno­tacji @Column  jak na przykładzie poniżej:

@Entity
@Table(name="koty")
public class Kot {

    @Column(name="imie_kota", nullable=false)
    private String imieKota;
    //...
}

Widz­imy tutaj dwie rzeczy: po pier­wsze wskazu­je­my, że pole imieKo­ta będzie zapisy­wane w kolum­nie o nazwie imie_kota, na dodatek nie może mieć wartoś­ci NULL (ustaw­iliśmy atry­but nul­lable na false [domyśl­nie jest true] — jeśli spróbu­je­my zapisać w bazie danych obiekt, który w tym polu będzie miał wartość null, otrzy­mamy błąd bazy danych.

Uwa­ga! Bard­zo częs­to będziemy mieli do wyboru dwie adno­tac­je o takiej samej nazwie, np:

Jest to spowodowane tym, że frame­work doda­je nowe możli­woś­ci i opc­je. Zasad­nic­zo, o ile nie potrze­bu­je­my naprawdę czegoś, co ofer­u­je bib­liote­ka, powin­niśmy uży­wać adno­tacji z paki­etu javax.persistence, ponieważ są to adno­tac­je stan­dar­d­owe JPA — korzys­tanie tylko z tych adno­tacji poz­woli w przyszłoś­ci pod­mienić imple­men­tację JPA tylko za pomocą konfiguracji.
To ogól­na zasa­da, o ile możli­we, powin­niśmy korzys­tać ze stan­dard­ów a nie z ich rozsz­erzeń zawsze, kiedy jest to możliwe.

EntityManager

Enti­ty­Man­ag­er to stan­dar­d­owy sposób wykony­wa­nia oper­acji na obiek­tach w stan­dard­zie JPA. Jak zobaczymy w drugiej częś­ci lekcji, skon­fig­u­ru­je­my fab­rykę (czyli sposób, w jaki będą automaty­cznie twor­zone Enti­ty­Man­agery), dzię­ki czemu będziemy mogli uży­wać Enti­ty­Man­agerów w naszych klasach.
Na dzisi­aj ważne jest, żeby pamię­tać o tym, że Enti­ty­Man­ag­er to nasz ‘most’ pomiędzy bazą danych a naszą aplikacją.

EntityManager vs Session

Powód, dla którego porusza­my dzisi­aj ten tem­at (o tym, jak go uży­wać powiemy sobie jutro) jest związany z alter­naty­wnym sposobem, z którym może­my się spotkać w wielu tuto­ri­alach, a mianowicie Sesją (Ses­sion­Fac­to­ry i Ses­sion). Role Ses­sion oraz Enti­ty­Man­ag­er są podob­ne, Ses­sion ma nieco więk­sze możli­woś­ci, ale Enti­ty­Man­ag­er jest częś­cią stan­dar­du (Ses­sion nie). Ma tu zas­tosowanie zasa­da, o której wspom­i­nałem wcześniej — jeśli nie potrze­bu­je­my koniecznie funkcjon­al­noś­ci Ses­sion, uży­wa­jmy stan­dard­ów — Enti­ty­Man­agera. Szerzej na ten tem­at wypowiedzi­ał się Emmanuel Bernard, Architekt w zes­pole pracu­ją­cym nad Hiber­nate w krótkim wywiadzie , pod­sumowu­jąc w skró­cie moż­na posłużyć się cytatem: “We encour­age peo­ple to use the EntityManager” .

W drugiej części

W drugiej częś­ci (już jutro) zobaczymy, jak dołączyć JPA do naszego pro­jek­tu i Springa oraz jak korzys­tać z JPA w naszych klasach DAO.

Licencja Creative Commons

Jeśli uważasz powyższą lekcję za przy­dat­ną, mamy małą prośbę: pol­ub nasz fan­page. Dzię­ki temu będziesz zawsze na bieżą­co z nowy­mi treś­ci­a­mi na blogu ( i oczy­wiś­cie, z nowy­mi częś­ci­a­mi kur­su Javy). Dzięki!