Mapim enum

Már kitaláltuk, hogyan lehet a primitív adattípusokat leképezni: a @Column annotációt és a @Type annotációt használjuk . De nem minden esetet fedhetnek le ezek a megjegyzések. És a leggyakoribb eset az enum .

A Java enum objektumok kétféleképpen tárolhatók az adatbázisban:

  • számként
  • mint egy húr

Írjunk egy kis példát, ahol a felhasználónak lesz egy kedvenc színe, amelyet az enum segítségével lehet beállítani.


enum Color {
   RED,
   ORANGE,
   YELLOW,
   GREEN,
   BLUE,
   VIOLET
}

És adjon hozzá egy színmezőt a User osztályhoz :


@Entity
@Table(name="user")
class User
{
   @Column(name="id")
   public Integer id;
 
   @Column(name="favorite_color")
   public Color favoriteColor;
 
   @Column(name="created_date")
   public Date createdDate;
}

Ha azt szeretnénk, hogy a Hibernate a Color típust az alapba mentse számként , akkor szükségünk van a mezőrekedvenc színmegjegyzés hozzáadása:


@Enumerated(EnumType.ORDINAL)

Ha azt szeretnénk, hogy az értékek karakterláncokként legyenek tárolva , akkor hozzá kell adnunk egy megjegyzést:


@Enumerated(EnumType.STRING)

Példa:


@Entity
@Table(name="user")
class User
{
   @Column(name="id")
   public Integer id;
 
   @Enumerated(EnumType.ORDINAL) //value will be saved to the base as a number
   @Column(name="favorite_color")
   public Color favoriteColor;
 
   @Column(name="created_date")
   public Date createdDate;
}

Mapim Boolean

A második hasznos forgatókönyv a logikai típusú leképezés. Történelmileg megtörtént, hogy az SQL-nek nincs saját adattípusa a Boolean-hez, és ott bármit használnak.

A három leggyakoribb lehetőség a következő:

  • 1 vagy 0
  • "F" vagy "T"
  • 'Y' vagy 'N'

Általánosságban elmondható, hogy ha a bázist tervezi, akkor jobb, ha azonnal megírja a BIT típust. Nos, a teljes leképezés így fog kinézni:


	@Column(name = "is_correct", columnDefinition = "BIT")
	@Type(type = "org.hibernate.type.NumericBooleanType")
    private Boolean isCorrect;

Nos, ha nem az adatbázist tervezi, nézze meg a fenti táblázatot, és gondolja át, hogyan lehet helyesen leképezni a szükséges típusokat.

Számított mezők

Néha az Entity osztály mezőinek száma és a táblázat oszlopainak száma nem egyezik. Ennek több oka is lehet.

A leggyakoribb az, amikor az Entity osztályunkban van olyan mező, amelyet nem szeretnénk elmenteni az adatbázisba. Ezzel minden világos - csak adja hozzá a @Transient megjegyzést egy ilyen mezőhöz , és a Hibernate figyelmen kívül hagyja az adatbázissal való munka során.

Példa:


@Entity(name = "Square")
public class Square {
           	@Id
           	public Long id;
 
           	public Integer width;
 
           	public Integer height;
 
           	@Transient
           	public Integer total;
}

Ez egy jó lehetőség, de egy objektum adatbázisból történő kiolvasásakor a teljes mező nulla lesz. És szeretnénk, ha benne lenne a szélesség*magasság szorzata. Ez hibernált állapotban is megtehető. Ehhez van egy speciális @Formula megjegyzés .


@Entity(name = "Square")
public class Square {
           	@Id
           	public Long id;
 
           	public Integer width;
 
           	public Integer height;
 
           	@Formula(value = " width * height ")
          	public Integer total;
}

Az ilyen mező nem kerül mentésre az adatbázisba, és az objektum adatbázisból való kiolvasásakor a képlettel számított érték kerül bele.

Az SQL lekérdezés valahogy így fog kinézni:

 SELECT id, width, height, (width* height) AS total FROM Square;

@Beágyazott

Egy másik hasznos megjegyzés az @Embedded . Lehetővé teszi, hogy a gyermek objektum mezőit magának az Entity osztálynak a mezőinek tekintse.

Tegyük fel, hogy van egy User osztálya , és úgy dönt, hogy hozzáad egy címet:


@Entity
@Table(name="user")
class User
{
   @Column(name="id")
    public Integer id;
 
   @Column(name="user_address_country")
   public String country;
   @Column(name="user_address_city")
   public String city;
   @Column(name="user_address_street")
   public String street;
   @Column(name="user_address_home")
   public String home;
 
   @Column(name="created_date")
    public Date createdDate;
}

Úgy tűnik, minden rendben van, de a Java szempontjából logikus lenne a címet külön osztályba tenni. A cím továbbra is külön entitás. De hogyan kell ezt megtenni, ha mindezt az információt a felhasználói táblában lévő adatbázisban tároljuk?

Az @Embedded annotáció segítségünkre lesz . Először létrehozzuk a UserAddress osztályt , és belehelyezzük a felhasználó címére vonatkozó összes információt:


@Embeddable
class UserAddress
{
   @Column(name="user_address_country")
   public String country;
   @Column(name="user_address_city")
   public String city;
   @Column(name="user_address_street")
   public String street;
   @Column(name="user_address_home")
   public String home;
}

Ezután ennek az osztálynak a mezőjét használjuk a Felhasználói osztályunkban :


@Entity
@Table(name="user")
class User
{
   @Column(name="id")
   public Integer id;
 
   @Embedded
   public UserAddress address;
 
   @Column(name="created_date")
   public Date createdDate;
}

Az @Embedded megjegyzésnek köszönhetően az objektum mentésekor a Hibernate megérti, hogy a UserAddress osztály mezőit magának a User osztálynak a mezőiként kell kezelni .

Fontos! Ha úgy dönt, hogy két UserAddress mezőt ad hozzá a User osztályhoz , akkor a @Embedded használata többé nem fog működni: ismétlődő mezői lesznek, és valahogy el kell választani őket. Ez a megjegyzések felülbírálásával történik: az @AttributeOverrides annotáció használatával .

Szeretném, ha ezt tudnád, de itt nem részletezzük. Szerintem ennyi elég ahhoz, hogy törd a fejed. A kíváncsiak számára hagyhatok egy linket a hivatalos dokumentációhoz .