Mapim枚舉

我們已經弄清楚瞭如何映射原始數據類型:我們使用@Column註釋和@Type註釋。但並非所有情況都可以被這些註釋覆蓋。最常見的情況是enum

Java 枚舉對象可以通過兩種方式存儲在數據庫中:

  • 作為一個數字
  • 作為一個字符串

讓我們寫一個小例子,用戶將有一個最喜歡的顏色,它是使用枚舉設置的。


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

如果我們希望 Hibernate 將 Color 類型作為數字保存到基中,那麼我們需要字段最喜歡的顏色添加註釋:


@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 布爾值

第二個有用的場景是布爾類型映射。歷史上確實發生過,SQL 沒有自己的 Boolean 數據類型,而是在那裡使用任何東西。

三個最常見的選項是:

  • 1 或 0
  • 'F' 或 'T'
  • “是”或“否”

一般來說,如果你要設計你的基地,那麼最好馬上寫下 BIT 類型。那麼,它的完整映射將如下所示:


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

好吧,如果你不是在設計數據庫,那就看看上表,想想如何正確映射你需要的類型。

計算字段

有時實體類中的字段數和表中的列數不匹配。這可能有幾個原因。

最常見的是當我們的實體類中有一些我們不想保存到數據庫的字段時。一切都清楚了 - 只需將@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。它允許您將子對象的字段視為實體類本身的字段。

假設您有一個User類,並且您決定向其添加一個地址:


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

然後我們在我們的用戶類中使用這個類的一個字段:


@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註釋。

我想讓你知道這一點,但我們不會在這裡詳細介紹。我認為這足以讓你打破你的頭。出於好奇,我可以留下官方文檔的鏈接。