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