มาพิม enum
เราได้ทราบวิธีแมปประเภทข้อมูลดั้งเดิมแล้ว: เราใช้ คำ อธิบาย ประกอบ @Columnและ คำอธิบายประกอบ @Type แต่ไม่ใช่ทุกกรณีที่สามารถครอบคลุมโดยคำอธิบายประกอบเหล่านี้ และกรณีที่พบบ่อยที่สุดคือenum
วัตถุ Java enum สามารถจัดเก็บในฐานข้อมูลได้สองวิธี:
- เป็นตัวเลข
- เป็นสตริง
ลองเขียนตัวอย่างเล็ก ๆ ที่ผู้ใช้จะมีสีโปรดซึ่งตั้งค่าโดยใช้ enum
enum Color {
RED,
ORANGE,
YELLOW,
GREEN,
BLUE,
VIOLET
}
และเพิ่มฟิลด์สีให้กับ คลาส User :
@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;
}
หากเราต้องการให้ไฮเบอร์เนตบันทึกประเภทสีเป็นฐานเป็นตัวเลขเราจำเป็นต้องมีฟิลด์นี้สีที่ชอบเพิ่มคำอธิบายประกอบ:
@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;
}
มาพิมบูลีน
สถานการณ์ที่มีประโยชน์ประการที่สองคือการแมปประเภทบูลีน มันเพิ่งเกิดขึ้นในอดีตที่ SQL ไม่มีประเภทข้อมูลของตัวเองสำหรับบูลีนและมีการใช้สิ่งใดแทน
สามตัวเลือกที่พบบ่อยที่สุดคือ:
- 1 หรือ 0
- 'F' หรือ 'T'
- 'ย' หรือ 'น'
โดยทั่วไป หากคุณกำลังจะออกแบบฐานของคุณ คุณควรเขียนประเภท BIT ทันที การแมปแบบเต็มสำหรับมันจะมีลักษณะดังนี้:
@Column(name = "is_correct", columnDefinition = "BIT")
@Type(type = "org.hibernate.type.NumericBooleanType")
private Boolean isCorrect;
ถ้าคุณไม่ได้ออกแบบฐานข้อมูล ให้ดูตารางด้านบนและคิดถึงวิธีแมปประเภทที่คุณต้องการให้ถูกต้อง
เขตข้อมูลจากการคำนวณ
บางครั้ง จำนวนฟิลด์ในคลาสเอนทิตีและจำนวนคอลัมน์ในตารางไม่ตรงกัน อาจมีสาเหตุหลายประการ
ที่พบบ่อยที่สุดคือเมื่อมีบางฟิลด์ในคลาสเอนทิตีของเราที่เราไม่ต้องการบันทึกลงในฐานข้อมูล ทุกอย่างชัดเจนด้วยสิ่งนี้ - เพียงเพิ่ม คำอธิบายประกอบ @Transient ลงในฟิลด์ดังกล่าว และไฮเบอร์เนตจะเพิกเฉยเมื่อทำงานกับฐานข้อมูล
ตัวอย่าง:
@Entity(name = "Square")
public class Square {
@Id
public Long id;
public Integer width;
public Integer height;
@Transient
public Integer total;
}
นี่เป็นตัวเลือกที่ดี แต่เมื่ออ่านวัตถุจากฐานข้อมูล ฟิลด์ทั้งหมดจะเป็นค่าว่าง และเราต้องการให้มีผลิตภัณฑ์ที่มีความกว้าง*สูง สิ่งนี้สามารถทำได้ในไฮเบอร์เนต มีคำอธิบายประกอบ @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
@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 การใส่ที่อยู่ในคลาสแยกต่างหากจะเป็นเรื่องสมเหตุสมผล ที่อยู่ยังคงเป็นนิติบุคคลแยกต่างหาก แต่จะทำอย่างไรหากข้อมูลทั้งหมดนี้เก็บไว้ในฐานข้อมูลในตารางผู้ใช้
คำอธิบาย ประกอบ @Embeddedจะช่วยเราได้ ก่อนอื่น เราจะสร้าง คลาส UserAddressและใส่ข้อมูลทั้งหมดเกี่ยวกับที่อยู่ของผู้ใช้ลงไป:
@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;
}
จากนั้นเราใช้ฟิลด์ของคลาสนี้ใน คลาส User ของเรา :
@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สอง ฟิลด์ในคลาส User ของคุณ การใช้@Embeddedจะไม่ทำงานอีกต่อไป: คุณจะมีช่องที่ซ้ำกันและคุณจะต้องแยกฟิลด์เหล่านี้ด้วยวิธีใดวิธีหนึ่ง สิ่งนี้ทำได้โดยการแทนที่คำอธิบายประกอบ: โดยใช้คำ อธิบายประกอบ @AttributeOverrides
ฉันต้องการให้คุณทราบสิ่งนี้ แต่เราจะไม่ลงรายละเอียดที่นี่ ฉันคิดว่าแค่นี้ก็เพียงพอแล้วที่คุณจะทุบหัวแตก สำหรับผู้ที่อยากรู้อยากเห็น ฉันสามารถฝากลิงก์ไปยังเอกสารทางการได้
GO TO FULL VERSION