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 .
GO TO FULL VERSION