Mapim enum

Vi har allerede funnet ut hvordan vi kartlegger primitive datatyper: vi bruker @Column- kommentaren og @Type- kommentaren . Men ikke alle tilfeller kan dekkes av disse merknadene. Og det vanligste tilfellet er enum .

Java enum-objekter kan lagres i databasen på to måter:

  • som et tall
  • som en streng

La oss skrive et lite eksempel hvor brukeren vil ha en favorittfarge, som settes ved hjelp av enum.


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

Og legg til et fargefelt i brukerklassen :


@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 at Hibernate skal lagre fargetypen til basen som tall , trenger vi feltetfavoritt fargelegg til merknad:


@Enumerated(EnumType.ORDINAL)

Hvis vi vil at verdiene skal lagres som strenger , må vi legge til en merknad:


@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 boolsk

Det andre nyttige scenariet er kartlegging av boolsk type. Det skjedde historisk at SQL ikke har sin egen datatype for boolsk og alt brukes der i stedet.

De tre vanligste alternativene er:

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

Generelt, hvis du skal designe basen din, er det bedre å skrive BIT-typen med en gang. Vel, den fullstendige kartleggingen for det vil se slik ut:


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

Vel, hvis du ikke designer databasen, så se tabellen ovenfor og tenk på hvordan du skal kartlegge typene du trenger.

Beregnede felt

Noen ganger stemmer ikke antall felt i en Entity-klasse og antall kolonner i en tabell. Det kan være flere årsaker til dette.

Det vanligste er når det er et felt i Entity-klassen vår som vi ikke ønsker å lagre i databasen. Alt er klart med dette - bare legg @Transient -kommentaren til et slikt felt og Hibernate vil ignorere det når du arbeider 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 et godt alternativ, men når du leser et objekt fra databasen, vil totalfeltet være null. Og vi vil gjerne at den skal inneholde produktet av bredde*høyde. Dette kan også gjøres i dvalemodus. Det er en spesiell @Formula- kommentar for 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 slikt felt vil ikke bli lagret i databasen, og når objektet leses fra databasen, vil verdien beregnet av formelen bli skrevet til det.

SQL-spørringen vil se omtrent slik ut:

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

@En del av

En annen nyttig merknad er @Embedded . Den lar deg vurdere feltene til det underordnede objektet som felt i selve Entity-klassen.

La oss si at du har en brukerklasse og bestemmer deg for å legge til 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 ut til å være bra, men fra Javas synspunkt ville det være logisk å sette adressen i en egen klasse. Adressen er fortsatt en egen enhet. Men hvordan gjøre dette hvis all denne informasjonen er lagret i databasen i brukertabellen?

@Embedded- kommentaren vil hjelpe oss . Først vil vi opprette UserAddress- klassen og legge all informasjon om brukerens adresse inn 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å bruker vi et felt av denne klassen i brukerklassen vår :


@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- kommentaren, vil Hibernate ved lagring av objektet forstå at feltene i UserAddress- klassen må behandles som felt i selve User- klassen .

Viktig! Hvis du bestemmer deg for å legge til to UserAddress- felt til brukerklassen din , vil bruken av @Embedded ikke lenger fungere: du vil ha dupliserte felt og du må skille dem fra hverandre på en eller annen måte. Dette gjøres ved å overstyre merknader: ved å bruke @AttributeOverrides -kommentaren .

Jeg vil at du skal vite dette, men vi vil ikke gå i detalj her. Jeg tror dette er nok til at du knekker hodet. For de nysgjerrige kan jeg legge igjen en lenke til den offisielle dokumentasjonen .