Mapim enum

Vi har allerede fundet ud af, hvordan man kortlægger primitive datatyper: vi bruger @Column- annotationen og @Type- annotationen . Men ikke alle sager kan dækkes af disse anmærkninger. Og det mest almindelige tilfælde er enum .

Java enum-objekter kan gemmes i databasen på to måder:

  • som et tal
  • som en snor

Lad os skrive et lille eksempel, hvor brugeren vil have en yndlingsfarve, som indstilles ved hjælp af enum.


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

Og tilføj et farvefelt til brugerklassen :


@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;
}

Hvis vi vil have Hibernate til at gemme farvetypen til basen som tal , så skal vi bruge feltetyndlingsfarvetilføje anmærkning:


@Enumerated(EnumType.ORDINAL)

Hvis vi ønsker, at værdierne skal gemmes som strenge , skal vi tilføje en anmærkning:


@Enumerated(EnumType.STRING)

Eksempel:


@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

Det andet nyttige scenarie er boolesk type kortlægning. Det skete bare så historisk, at SQL ikke har sin egen datatype for Boolean, og noget bliver brugt der i stedet.

De tre mest almindelige muligheder er:

  • 1 eller 0
  • 'F' eller 'T'
  • 'Y' eller 'N'

Generelt, hvis du skal designe din base, så er det bedre at skrive BIT-typen med det samme. Nå, den fulde kortlægning for det vil se sådan ud:


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

Nå, hvis du ikke designer databasen, så se tabellen ovenfor og tænk på, hvordan du korrekt kortlægger de typer, du har brug for.

Beregnede felter

Nogle gange stemmer antallet af felter i en enhedsklasse og antallet af kolonner i en tabel ikke. Det kan der være flere årsager til.

Det mest almindelige er, når der er et felt i vores Entity-klasse, som vi ikke ønsker at gemme i databasen. Alt er klart med dette - bare føj @Transient annotationen til et sådant felt , og Hibernate vil ignorere det, når du arbejder med databasen.

Eksempel:


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

Dette er en god mulighed, men når du læser et objekt fra databasen, vil det samlede felt være null. Og vi vil gerne have, at den indeholder produktet af bredde*højde. Dette kan også gøres i Hibernate. Der er en speciel @Formula- annotation til dette .


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

Et sådant felt vil ikke blive gemt i databasen, og når objektet læses fra databasen, vil værdien beregnet af formlen blive skrevet til det.

SQL-forespørgslen vil se nogenlunde sådan ud:

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

@Indlejret

En anden nyttig annotation er @Embedded . Det giver dig mulighed for at betragte felterne i det underordnede objekt som felter i selve Entity-klassen.

Lad os sige, at du har en brugerklasse , og du beslutter dig for at tilføje en adresse til den:


@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;
}

Alt ser ud til at være i orden, men fra Javas synspunkt ville det være logisk at placere adressen i en separat klasse. Adressen er stadig en separat enhed. Men hvordan gør man dette, hvis al denne information er gemt i databasen i brugertabellen?

@Embedded- annotationen vil hjælpe os . Først vil vi oprette klassen UserAddress og lægge alle oplysningerne om brugerens adresse ind i den:


@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;
}

Og så bruger vi et felt af denne klasse i vores brugerklasse :


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

Takket være @Embedded- annotationen vil Hibernate på tidspunktet for lagring af objektet forstå, at felterne i klassen UserAddress skal behandles som felter i selve brugerklassen .

Vigtig! Hvis du beslutter dig for at tilføje to UserAddress- felter til din brugerklasse , vil brugen af ​​@Embedded ikke længere virke: du vil have duplikerede felter, og du bliver nødt til at adskille dem på en eller anden måde. Dette gøres ved at tilsidesætte annoteringer: ved at bruge @AttributeOverrides -annotationen .

Jeg vil have dig til at vide det, men vi vil ikke gå i detaljer her. Jeg tror, ​​det er nok til, at du kan knække dit hoved. For de nysgerrige kan jeg efterlade et link til den officielle dokumentation .