在使用實體類生成對應的資料庫表時,很多的時候都會遇到這種情況:在一個實體類中引用另外的實體類,一般遇上這種情況,我們使用<code>@OneToOne</code>、<code>@OneToMany</code>、<code>@ManyToOne</code>、<code>@ManyToMany</code>這4個注解比較多,但是好奇害死貓,除了這四個有沒有别的使用情況,尤其是一個實體類要在多個不同的實體類中進行使用,而本身又不需要獨立生成一個資料庫表,這就是需要<code>@Embedded</code>、<code>@Embeddable</code>的時候了,下面分成4類來說明在一個實體類中引用另外的實體類的情況,具體的資料庫環境是MySQL 5.7。
使用的兩個實體類如下:
Address類
Person類:
當這兩個注解都不使用時,那麼兩個實體類和上面的相同,那麼生成的表結構如下:

Address屬性字段會映射成tinyblob類型的字段,這是用來存儲不超過255字元的二進制字元串的資料類型,顯然我們通常不會這麼使用。
我們在Address實體類上加上<code>@Embeddable</code>注解,變成如下類:
而Person實體類不變,生成的資料庫表結構如下:
可以看出這次是把Address中的字段映射成資料庫列嵌入到Person表中了,而這些字段的類型和長度也使用預設值。如果我們在Address中的字段中設定列的相關屬性,則會按照我們設定的值去生成,如下Address類:
生成的表結構如下:
我們在Address中配置的屬性全部成功映射到Person表中。
這裡我們隻在Person中使用<code>@Embedded</code>,如下:
Adddress類和最開始的不同POJO類相同,此時生成的表結構如下:
可以看出這個表結構和在Address中隻使用<code>@Embeddable</code>注解時相同,在進入深一步試驗,我們在Address中加入列屬性,但是不使用<code>@Embeddable</code>注解會發生什麼?
Address類如下:
生成資料表結構如下:
是以隻使用<code>@Embedded</code>和隻使用<code>@Embeddable</code>産生的效果是相同的。
既然單獨使用<code>@Embedded</code>或者隻使用<code>@Embeddable</code>都會産生作用,那麼這兩個都使用效果也一定是一樣的,我們平時也是這麼用的。是以在這部分我們就不示範和上面相同的效果了,而是說兩個深入的話題。
這裡就要使用另外的兩個注解<code>@AttributeOverrides</code>和<code>@AttributeOverride</code>,這兩個注解是用來覆寫<code>@Embeddable</code>類中字段的屬性的。
<code>@AttributeOverrides</code>:裡面隻包含了<code>@AttributeOverride</code>類型數組;
<code>@AttributeOverride</code>:包含要覆寫的<code>@Embeddable</code>類中字段名name和新增的<code>@Column</code>字段的屬性;
使用如下:
Person類如下:
生成的資料表如下:
可以看出我們的<code>@AttributeOverrides</code>和<code>@AttributeOverride</code>兩個注解起作用了。
上面所有的例子都是使用兩層實體類嵌入,其實這種實體類的嵌入映射是可以使用多層的,具體的例子如下。
我們建立立一個類Direction表示方位如下:
Address如下:
在上面需要注意如下幾點:
在Person中定義Direction中的屬性時,需要用”.”将所有相關的屬性連接配接起來;
在Direction中longitude屬性定義為<code>not null</code>,但是由于使用了<code>@AttributeOverride</code>注解,其中雖然沒有定義null屬性,但是這時使用的是預設的nullable屬性,預設為true;