Prevodníky atribútov JPA

1. Úvod

V tomto článku sa budeme venovať použitiu prevodníkov atribútov dostupných v JPA 2.1, ktoré nám zjednodušene umožňujú mapovať typy JDBC na triedy Java.

Tu použijeme Hibernate 5 ako našu implementáciu JPA.

2. Vytvorenie prevádzača

Ukážeme si, ako implementovať prevodník atribútov pre vlastnú triedu Java.

Najskôr vytvorme a PersonName trieda - ktorá bude prevedená neskôr:

verejná trieda PersonName implementuje Serializable {private String name; súkromné ​​priezvisko; // zakladatelia a zakladatelia}

Potom pridáme atribút typu PersonName do an @Entity trieda:

@Entity (name = "PersonTable") verejná trieda Osoba {private PersonName personName; // ...}

Teraz musíme vytvoriť prevodník, ktorý transformuje PersonName atribút do stĺpca databázy a naopak. V našom prípade prevedieme atribút na a String hodnota, ktorá obsahuje polia pre meno a priezvisko.

Urobiť tak musíme anotovať našu triedu prevodníkov pomocou @Converter a implementovať AttributeConverter rozhranie. Parametrizujeme rozhranie s typmi triedy a stĺpcom databázy v tomto poradí:

@ Verzia publicConverter PersonNameConverter implementuje AttributeConverter {private static final String SEPARATOR = ","; @Override public String convertToDatabaseColumn (PersonName personName) {if (personName == null) {return null; } StringBuilder sb = nový StringBuilder (); if (personName.getSurname ()! = null &&! personName.getSurname () .isEmpty ()) {sb.append (personName.getSurname ()); sb.append (SEPARATOR); } if (personName.getName ()! = null &&! personName.getName (). isEmpty ()) {sb.append (personName.getName ()); } návrat sb.toString (); } @Override public PersonName convertToEntityAttribute (String dbPersonName) {if (dbPersonName == null || dbPersonName.isEmpty ()) {return null; } Reťazec [] pieces = dbPersonName.split (SEPARATOR); if (pieces == null || pieces.length == 0) {return null; } PersonName personName = new PersonName (); String firstPiece =! Kusov [0] .isEmpty ()? kúsky [0]: null; if (dbPersonName.contains (SEPARATOR)) {personName.setSurname (firstPiece); if (kusov.lenka> = 2 && kusov [1]! = null &&! kusov [1] .isEmpty ()) {personName.setName (kusov [1]); }} else {personName.setName (firstPiece); } vrátiť osobu; }}

Všimnite si, že sme museli implementovať 2 metódy: convertToDatabaseColumn () a convertToEntityAttribute ().

Tieto dve metódy sa používajú na prevod z atribútu na databázový stĺpec a naopak.

3. Používanie prevodníka

Ak chcete použiť náš prevodník, stačí pridať @Convert anotáciu k atribútu a zadajte triedu prevodníka, ktorú chceme použiť:

@Entity (name = "PersonTable") verejná trieda Person {@Convert (converter = PersonNameConverter.class) súkromné ​​PersonName PersonName; // ...}

Na záver vytvoríme test jednotky, aby sme zistili, či to naozaj funguje.

Aby sme to mohli urobiť, najskôr uložíme a Osoba objekt v našej databáze:

@Test public void givenPersonName_whenSaving_thenNameAndSurnameConcat () {Názov reťazca = "meno"; Reťazec priezvisko = "priezvisko"; PersonName personName = new PersonName (); personName.setName (meno); personName.setSurname (priezvisko); Osoba osoba = nová Osoba (); person.setPersonName (personName); Long id = (Long) session.save (person); session.flush (); session.clear (); }

Ďalej to otestujeme PersonName bol uložený tak, ako sme ho definovali v prevádzači - načítaním tohto poľa z databázovej tabuľky:

@ Test public void givenPersonName_whenSaving_thenNameAndSurnameConcat () {// ... String dbPersonName = (String) session.createNativeQuery ("vyberte p.personName z PersonTable p kde p.id =: id") .setParameter ("id", id). getSingleResult (); assertEquals (priezvisko + "," + meno, dbPersonName); }

Vyskúšajme tiež, že prevod z hodnoty uloženej v databáze na PersonName trieda funguje tak, ako je definované v prevádzači, napísaním dotazu, ktorý načíta celý Osoba trieda:

@Test public void givenPersonName_whenSaving_thenNameAndSurnameConcat () {// ... Osoba dbPerson = session.createNativeQuery ("select * z PersonTable p, kde p.id =: id", Person.class) .setParameter ("id", id) .getSingleResult (); assertEquals (dbPerson.getPersonName () .getName (), meno); assertEquals (dbPerson.getPersonName () .getSurname (), priezvisko); }

4. Záver

V tomto krátkom tutoriáli sme si ukázali, ako používať novo zavedené prevádzače atribútov v JPA 2.1.

Úplný zdrojový kód príkladov je ako vždy k dispozícii na serveri GitHub.