Mapim enum
Вече разбрахме How да картографираме примитивни типове данни: използваме анотацията @Column и анотацията @Type . Но не всички случаи могат да бъдат обхванати от тези анотации. И най-често срещаният случай е enum .
Java enum обектите могат да се съхраняват в базата данни по два начина:
- като число
- като низ
Нека напишем малък пример, където потребителят ще има любим цвят, който се задава с помощта на enum.
enum Color {
RED,
ORANGE,
YELLOW,
GREEN,
BLUE,
VIOLET
}
И добавете цветно поле към потребителския клас :
@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;
}
Ако искаме Hibernate да запази типа цвят в основата като числа , тогава имаме нужда от полетолюбим цвятдобавете анотация:
@Enumerated(EnumType.ORDINAL)
Ако искаме стойностите да се съхраняват като низове , тогава трябва да добавим анотация:
@Enumerated(EnumType.STRING)
Пример:
@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
Вторият полезен сценарий е картографиране на булев тип. Исторически се случи така, че SQL няма собствен тип данни за Boolean и instead of това там се използва всичко.
Трите най-често срещани опции са:
- 1 or 0
- „F“ or „T“
- „Да“ or „Н“
Като цяло, ако ще проектирате вашата база, тогава е по-добре да напишете типа BIT веднага. Е, пълното картографиране за него ще изглежда така:
@Column(name = "is_correct", columnDefinition = "BIT")
@Type(type = "org.hibernate.type.NumericBooleanType")
private Boolean isCorrect;
Е, ако не проектирате базата данни, вижте tableта по-горе и помислете How да картографирате правилно типовете, от които се нуждаете.
Изчисляеми полета
Понякога броят на полетата в клас Entity и броят на колоните в table не съвпадат. Може да има няколко причини за това.
Най-често срещаният е, когато има няHowво поле в нашия клас Entity, което не искаме да запазим в базата данни. С това всичко е ясно - просто добавете анотацията @Transient към такова поле и Hibernate ще го игнорира, когато работи с базата данни.
Пример:
@Entity(name = "Square")
public class Square {
@Id
public Long id;
public Integer width;
public Integer height;
@Transient
public Integer total;
}
Това е добра опция, но при четене на обект от базата данни, общото поле ще бъде нула. И бихме искали да съдържа произведението от ширина*височина. Това може да се направи и в Hibernate. За това има специална анотация @Formula .
@Entity(name = "Square")
public class Square {
@Id
public Long id;
public Integer width;
public Integer height;
@Formula(value = " width * height ")
public Integer total;
}
Такова поле няма да бъде запазено в базата данни и когато обектът бъде прочетен от базата данни, стойността, изчислена по формулата, ще бъде записана в него.
SQL заявката ще изглежда така:
SELECT id, width, height, (width* height) AS total FROM Square;
@Вграден
Друга полезна анотация е @Embedded . Тя ви позволява да разглеждате полетата на дъщерния обект като полета на самия клас Entity.
Да приемем, че имате потребителски клас и решите да добавите address към него:
@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;
}
Всичко изглежда наред, но от гледна точка на Java би било логично addressът да се постави в отделен клас. Адресът все още е отделна единица. Но How да направите това, ако цялата тази информация се съхранява в базата данни в потребителската table?
Анотацията @Embedded ще ни помогне . Първо ще създадем класа UserAddress и ще поставим цялата информация за address на потребителя в него:
@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;
}
След това използваме поле от този клас в нашия потребителски клас :
@Entity
@Table(name="user")
class User
{
@Column(name="id")
public Integer id;
@Embedded
public UserAddress address;
@Column(name="created_date")
public Date createdDate;
}
Благодарение на анотацията @Embedded , в момента на запазване на обекта, Hibernate ще разбере, че полетата на класа UserAddress трябва да се третират като полета на самия клас User .
важно! Ако решите да добавите две полета UserAddress към вашия потребителски клас , тогава използването на @Embedded вече няма да работи: ще имате дублиращи се полета и ще трябва да ги разделите по няHowъв начин. Това се прави чрез замяна на анотациите: с помощта на анотацията @AttributeOverrides .
Искам да знаете това, но няма да навлизаме в подробности тук. Мисля, че това е достатъчно, за да си счупиш главата. За любопитните мога да оставя линк към официалната documentация .
GO TO FULL VERSION