bản đồ enum

Chúng tôi đã tìm ra cách ánh xạ các kiểu dữ liệu nguyên thủy: chúng tôi sử dụng chú thích @Column và chú thích @Type . Nhưng không phải tất cả các trường hợp đều có thể được bao phủ bởi các chú thích này. Và trường hợp phổ biến nhất là enum .

Các đối tượng enum trong Java có thể được lưu trữ trong cơ sở dữ liệu theo hai cách:

  • như một con số
  • như một chuỗi

Hãy viết một ví dụ nhỏ trong đó người dùng sẽ có một màu yêu thích, được đặt bằng cách sử dụng enum.


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

Và thêm một trường màu vào lớp Người dùng :


@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;
}

Nếu chúng ta muốn Hibernate lưu loại Màu vào cơ sở dưới dạng số , thì chúng ta cần trườngMàu sắc yêu thíchthêm chú thích:


@Enumerated(EnumType.ORDINAL)

Nếu chúng ta muốn các giá trị được lưu trữ dưới dạng chuỗi thì chúng ta cần thêm chú thích:


@Enumerated(EnumType.STRING)

Ví dụ:


@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;
}

Bản đồ Boolean

Kịch bản hữu ích thứ hai là ánh xạ kiểu boolean. Nó chỉ xảy ra trong lịch sử rằng SQL không có kiểu dữ liệu riêng cho Boolean và thay vào đó, mọi thứ được sử dụng ở đó.

Ba tùy chọn phổ biến nhất là:

  • 1 hoặc 0
  • 'F' hoặc 'T'
  • 'Y' hoặc 'N'

Nói chung, nếu bạn định thiết kế cơ sở của mình, thì tốt hơn hết bạn nên viết loại BIT ngay lập tức. Chà, ánh xạ đầy đủ cho nó sẽ như thế này:


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

Chà, nếu bạn không thiết kế cơ sở dữ liệu, thì hãy xem bảng trên và suy nghĩ về cách ánh xạ chính xác các loại bạn cần.

Các trường được tính toán

Đôi khi số trường trong một lớp Thực thể và số cột trong bảng không khớp. Có thể có một số lý do cho việc này.

Phổ biến nhất là khi có một số trường trong lớp Thực thể của chúng tôi mà chúng tôi không muốn lưu vào cơ sở dữ liệu. Mọi thứ đều rõ ràng với điều này - chỉ cần thêm chú thích @Transient vào trường như vậy và Hibernate sẽ bỏ qua nó khi làm việc với cơ sở dữ liệu.

Ví dụ:


@Entity(name = "Square")
public class Square {
           	@Id
           	public Long id;
 
           	public Integer width;
 
           	public Integer height;
 
           	@Transient
           	public Integer total;
}

Đây là một tùy chọn tốt, nhưng khi đọc một đối tượng từ cơ sở dữ liệu, trường tổng số sẽ là null. Và chúng tôi muốn nó chứa tích của chiều rộng * chiều cao. Điều này cũng có thể được thực hiện trong Hibernate. Có một chú thích @Formula đặc biệt cho điều này .


@Entity(name = "Square")
public class Square {
           	@Id
           	public Long id;
 
           	public Integer width;
 
           	public Integer height;
 
           	@Formula(value = " width * height ")
          	public Integer total;
}

Trường như vậy sẽ không được lưu vào cơ sở dữ liệu và khi đối tượng được đọc từ cơ sở dữ liệu, giá trị được tính theo công thức sẽ được ghi vào trường đó.

Truy vấn SQL sẽ giống như thế này:

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

@Embedded

Một chú thích hữu ích khác là @Embedded . Nó cho phép bạn coi các trường của đối tượng con là các trường của chính lớp Thực thể.

Giả sử bạn có một lớp Người dùng và bạn quyết định thêm một địa chỉ vào lớp đó:


@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;
}

Mọi thứ có vẻ ổn, nhưng theo quan điểm của Java, sẽ hợp lý nếu đặt địa chỉ vào một lớp riêng biệt. Địa chỉ vẫn là một thực thể riêng biệt. Nhưng làm thế nào để làm điều này nếu tất cả thông tin này được lưu trữ trong cơ sở dữ liệu trong bảng người dùng?

Chú thích @Embedded sẽ giúp ích cho chúng ta . Đầu tiên, chúng ta sẽ tạo lớp UserAddress và đưa tất cả thông tin về địa chỉ của người dùng vào đó:


@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;
}

Và sau đó chúng tôi sử dụng một trường của lớp này trong lớp Người dùng của chúng tôi :


@Entity
@Table(name="user")
class User
{
   @Column(name="id")
   public Integer id;
 
   @Embedded
   public UserAddress address;
 
   @Column(name="created_date")
   public Date createdDate;
}

Nhờ có chú thích @Embedded mà tại thời điểm lưu đối tượng, Hibernate sẽ hiểu rằng các trường của lớp UserAddress cần được coi như các trường của chính lớp Người dùng .

Quan trọng! Nếu bạn quyết định thêm hai trường Địa chỉ người dùng vào lớp Người dùng của mình thì việc sử dụng @Embedded sẽ không còn hiệu quả nữa: bạn sẽ có các trường trùng lặp và bạn sẽ cần tách chúng ra bằng cách nào đó. Điều này được thực hiện bằng cách ghi đè chú thích: sử dụng chú thích @AttributeOverrides .

Tôi muốn bạn biết điều này, nhưng chúng tôi sẽ không đi vào chi tiết ở đây. Tôi nghĩ điều này là đủ cho bạn để phá vỡ đầu của bạn. Đối với những người tò mò, tôi có thể để lại liên kết đến tài liệu chính thức .