3. Entitats
1. Mapeig d'Entitas. Beans
Un cop estudiat la configuració inicial, és el moment de mapejar les nostres entitats i relacions. Partint del model relacional, anem a fer servir aquesta entitat Peli:
| SQL | |
|---|---|
Ací tens un script DBCine.sql per a treballar. La classe que encapsula la pel·lícula serà alguna cosa semblant a:
Recordatori
Recorda que pots utilitzar la llibreria Lombok per crear beans de manera més ràpida.
2. Arxius de Mapeig
El bean creat a la última secció encara no es pot persistir. Per fer-ho, hem de crear un fitxer extern a la classe, amb l'extensió hbm.xml i amb el mateix nom que la classe (Hibernate Mapping). La ubicació del fitxer no importa, però és una bona idea guardar les classes del model en un lloc i els fitxers de mapeig en un altre.
Així que crearem un paquet orm i dins d'aquest, crearem el fitxer Peli.hbm.xml. Anem a explicar-ho amb un exemple, ja que la sintaxi és bastant extensa.
Fixar-se en els conceptes bàsics:
- Les línies 1-3 són la capçalera XML, que apunta al fitxer DTD amb la gramàtica per comprovar que el fitxer està ben format.
<hibernate-mapping>\(\rightarrow\) indica que aquest fitxer és un mapeig.<class>\(\rightarrow\) és l'etiqueta per especificar quina classe estem mapejant i té dos atributs:name="Model.Peli"\(\rightarrow\) apunta a la classe (fitxer Java), sense extensió.table="Peli"\(\rightarrow\) aquí escrivim el nom de la taula a la base de dades que contindrà les dades.
- Cal especificar els camps de la classe i les seves respectives columnes. Distingim entre:
<property>\(\rightarrow\) per als camps normals. Pot tenir diversos atributs:name\(\rightarrow\) (obligatori) és el nom del camp dins de la classe.column\(\rightarrow\) és el nom de la columna corresponent a la taula. Si no s'especificacolumn, Hibernate assumirà que és el mateix que l'atributname.type\(\rightarrow\) és el tipus de dades de Java de la columna. Per defecte, Hibernate utilitzarà el mateix que el especificat per la classe, però cal indicar-ho per resoldre camps ambigus (mira la figura següent, especialment en els formats de data i hora).
<id>\(\rightarrow\) (obligatori) és el camp que s'utilitzarà com a clau primària i també pot tenir els atributs name, column i type. Existeix la possibilitat que la clau primària sigui generada pel sistema de gestió de bases de dades (DBMS), i ho indicarem amb:<generator>\(\rightarrow\) estableix el motor per generar la clau primària, que pot ser especificat de diverses maneres. Ambnativeutilitzem el mateix mètode de la base de dades subjacent. En aquest tutorial pots trobar exemples complets enllaç
Atenció
- Has de desar aquest fitxer perquè sigui accessible en el nostre projecte. Una bona opció és crear una carpeta
resourcesdins desrc/maini desar aquests fitxers a l'interior. - Hibernate necessita mètodes get/set per accedir als camps dels nostres objectes. No obstant això, potser no vols crear cap mètode, però Hibernate ho necessita. La solució és afegir un nou atribut
access=fieldque permet a Hibernate accedir als camps sense getters i setters.

Atenció
Estudiarem més opcions com les claus externes en les pròximes seccions.
Ara estudiarem un xicotet programa:
Comentaris:
- Cal tenir en compte que per desar un objecte (per exemple, inserir una fila a la base de dades), només cal executar
Session.save(Object). - Per obtenir un objecte de la base de dades, hi ha una manera senzilla, coneixent la classe i la clau primària de l'objecte. El mètode és
Session.get(class,ID), i obtenim un objecte d'aquesta classe amb aquesta ID. - Cal tenir en compte que quan creem un objecte nou, no té una ID (recorda que és generada automàticament), però quan el desem, se li assigna una nova ID.
Recorda
Si triem create a la propietat hbm2ddl.auto, com ja suposaràs, la base de dades estarà buida. És una bona idea crear un fitxer anomenat imports.sql amb algunes dades necessàries per provar els nostres programes.
3. Mapejant classes. Anotacions.
Abans de començar a anotar classes, deixem que us mostri això:
-
JDO (Java Data Objects) és un estàndard de persistència desenvolupat per Apache, que inclou un marc de treball de persistència basat en post-compilació. Tot i intentar aconseguir una tècnica més eficient, hi ha poques iniciatives comercials que segueixen aquest estàndard.
-
L'alternativa és JPA (Java Persistance API), un estàndard de persistència incorporat a JDK 5, amb diverses llibreries que el suporten, i basat en el principi de la reflexió, que utilitza metadades així com informació sobre les classes i l'estructura perquè la màquina virtual pugui accedir a la informació recopilada dels objectes per invocar els seus mètodes i construir noves instàncies. Les dues ORM més implementades en Java: Hibernate i EJB utilitzen aquest estàndard.
Mapejar classes és fàcil, i només cal emparellar cada camp amb cada columna. L'inconvenient és que necessitem mantenir dos fitxers: classes i fitxers de mapeig. Per aquest motiu, podem unir tots dos elements, afegint dins de les classes les anotacions específiques per fer l'emparellament. La interfície JPA ens permet fer aquesta tasca.
Anem a mostrar una classe amb anotacions i comparar-la amb els fitxers de mapeig. A més, farem servir Lombok per crear la classe, que també utilitza anotacions ;).
Informació
Hibernate primer creà les anotacions del paquet org.hibenate.annotations, però des de la versió 4 està depreciat, i s'ha d'importar des de javax.persistence
Anem a veure les principals anotacions, tot i que en tindràs moltes més a la documentació de JPA:
@Entityper indicar que aquesta classe representa una entitat a la nostra base de dades. A més, hem d'associar aquesta entitat a una@Tableamb el nom correcte.- Per definir els camps de la base de dades, hem d'utilitzar
@Column. Pots especificar més opcions, especialment si el nom de la columna és diferent del nom del camp. Consulta la següent imatge per a més opcions. Una opció interessant és establir un valor generat automàticament amb@GeneratedValue. Si no especifiques l'opcióname, es suposa que és el mateix. - Per marcar un camp com a clau primària, necessites
@Id. En aquest cas, no cal que ho especifiquis amb@Column.
4. Components
Anem a revisar un patró de disseny especial, que és l'agregació. Aquest patró s'utilitza quan necessitem una entitat que només té sentit dins d'una altra entitat, per exemple, una roda no té sentit fora d'un cotxe. Si l'entitat pot existir per si sola, és quan utilitzem una relació, i ho estudiarem a la següent secció.
La classe agregada també es coneix com a component.
Compte
Aquests components també es poden substituir per una relació 1:1 amb una restricció d'existència, quan en el procés de normalització es junten a la mateixa taula.
Per crear un component, la classe agregada s'ha de definir amb @Embeddable (i, òbviament, sense @Entity). Aquesta anotació indica a Hibernate que l'existència d'aquests objectes ha d'estar dins d'altres objectes. Dins d'aquests objectes, com a camps, els objectes s'han de marcar amb @Embedded. Anem a veure un exemple:
Un component Roda (Wheel
| Java | |
|---|---|
An aggregation CarWheel
Quan Hibernate crea la taula, cal tenir en compte que no es crearà cap taula Wheel. En canvi, tots els camps estan dins de CarWheel. Els dos últims camps són propietats de la classe Wheel.
| SQL | |
|---|---|
Atenció Pot aparèixer un problema quan intentes desar dos components incrustats, per exemple dues adreces d'un empleat, ja que Hibernate crea camps a partir de la classe del component i els noms dels camps es duplicaran. Per evitar aquest inconvenient, la solució és canviar el nom dels camps de la classe del component, com es mostra a continuació (dins de la classe agregada):
| Java | |
|---|---|
Fixa't que:
- El primer camp incrustat no necessita res especial.
- En el segon, hem de sobreescriure els noms dels atributs, començant amb
@AttributeOverridesamb diversos@AttributeOverride, indicant el nom antic i el nou nom de la columna.
Però...
Aquesta situació no és habitual, però és important resoldre-la quan sigui necessari.
5. Exercici
Realitza la següent tasca:
- Crea un projecte Maven i afegeix totes les dependències que necessitis.
- Crea dues classes per tu mateix, però pensant que estaran relacionades en un futur. Per exemple, Professor i Tema, o Conductor i Cotxe, o Mascota i Veterinari. En aquest moment no cal que creïs cap relació.
- Cada classe ha de tenir una ID i almenys 4 camps, amb diversos tipus de dades (no cal que tots siguin camps de tipus String).
- Mapeja les dues classes:
- Una amb un fitxer XML extern.
- L'altra amb anotacions JPA.
- Crea una aplicació principal on demanis a l'usuari les dades i les emmagatzemis (i les desis) a la mateixa base de dades.