@JoinTable和@JoinColumn


在address中沒有特殊的注解。

在Person中對應到數據庫里面就有一個指向Address的外鍵.

我們也可以增加注釋指定外鍵的列的名字,如下:

@OneToOne(cascade=CascadeType.ALL,optional=true) @JoinColumn(name="addressID")//注釋本表中指向另一個表的外鍵。    
 public Address getAddress() {
         return address;
 }


如果我們不加的話,也是可以通過的,在JBOSS里面,它會自動幫你生成你指向這個類的類名加上下划線再加上id的列,也就是默認列名是:address_id.
如果是主鍵相關聯的話,那么可以運用如下注釋

@OneToOne(cascade={CascadeType.ALL})    
@PrimaryKeyJoinColumn    
public Address getAddress( ) {
       return homeAddress;
}

它表示兩張表的關聯是根據兩張表的主鍵的

—————————————————————————————————————————————————————————————————————

2.person和phone的一對多單向關系:

phone中沒有特別的注釋。

person中:

@OneToMany(cascade=CascadeType.ALL)  
@JoinColumn(name="personID")//注釋的是另一個表指向本表的外鍵。  
public List<Phone> getPhones() {
        return phones;     
 }

我們可以在Person類里面發現@JoinColumn(name="personID")
它代表是一對多,一是指類本身,多是指這個成員,也就是一個類可以對應多個成員.
在一對多里面,無論是單向還是雙向,映射關系的維護端都是在多的那一方,也就是 Phone那里,因為要在數據庫面表現的話,也只有讓Phone起一個指向Person的外鍵,不可能在Person里面指向Phone,這一點和一對一 不一樣,一對一可以在任意一方起一個外鍵指向對方.可是一對多卻不行了.

在這里@JoinColumn這個注釋指的卻是在Phone里面的外鍵的列的名字,

它並不像在一對一里面的注釋指的是自己表里面的外鍵列名.這一點要特別注意一下.


如果是一對多的雙向關系,那么這個注釋就要應用到多的那邊去了,雖然注釋還在Person類里面,但是它起的效果卻是在Phone里面起一個叫personID的外鍵, 因為多的那邊要有外鍵指向少的這邊.
如果你不加 @JoinColumn(name="personID")這個注釋的話,那么JBOSS就會自動幫你生成一張中間表,

它負現Person和Phone表之間的聯系.它將會做如下事情:

 

CREATE TABLE
    PERSON_PHONE
    (
        PERSON_id INT,
        PHONE_id INT
    );
ALTER TABLE
    PERSON_PHONE ADDCONSTRAINT person_phone_unique UNIQUE (PHONE_id);
ALTER TABLE
    PERSON_PHONE ADDCONSTRAINT personREFphone FOREIGNKEY (PERSON_id) REFERENCES PERSON (id);
ALTER TABLE
    PERSON_PHONE ADDCONSTRAINT personREFphone2 FOREIGNKEY (PHONE_id) REFERENCES PHONE (id);    

 

 

所以我們最好還是指定一下,以讓程序產生更加確定的行為,不過一般是推薦另外生成一 個中間表好一些,因為這樣的話,對原來兩張表的結構不對造成任何影響。在遺留系統的時候很多用,有些時候,一些表都是以前就建好了的,要改表的結構是不太 可能的,所以這個時候中間的表就顯得很重要了,它可以在不侵入原來表的情況下構建出一種更清淅更易管理的關系。

所以一對多的單向關聯,我們還是推薦使用一張中間表來建立關系。

-----------------------------------------------------------------------------------------------------------------------------------

3.person和country的多對一單向關系:

country中無特別的注解。

而person注解如下:

 

@ManyToOne  @JoinColumn(name="countryID")      
public Country getCountry() {
          return country;      
} 

 

 

 在一對多一對多一對的關系里面,關系的維護端都是在多的那一面,多的一面為主控方,擁有指向對方的外鍵。

因為主控端是Person .外鍵也是建在Person上面,因為它是多的一面。當然我們在這里也可以省掉@JoinColumn,那樣的話會怎么樣呢,會不會像一對多單向一樣生成中間的表呢?事實是不會的,在這里如果我們去掉@JoinColumn的話,那么一樣會在Person表里面生成一列指向

Country的外鍵,這一點和一對多的單向是不一樣,在一對多的單向里面,如果我們不在Person 里面加上@JoinColumn這個注釋,那么JBOSS將會為我們生成一個中間的表,這個表會有一個列指向Person主鍵,一個列指向Phone主鍵。所以說為了程序有一定的行為,有些東西我們還是不要省的好。
其實多對一單向是有點向一對一單向的,在主控端里面,也就是從Person的角度來看,也就是對應了一個Country而已,只不過這個Country是很多Person所共用的,而一對一卻沒有這一點限制。

------------------------------------------------------------

4.person和project的多對多單向關系:

project沒有特殊的注解。

person:

@ManyToMany
 public List<Project> getProjects() {
     return projects;     
 }

它需要設置中間表來維護關系,在數據庫上跟多對多雙向,只不過在編程的邏輯中不一樣而已。

//類似這個:@JoinTable(name = "PersonANDFlight", joinColumns ={@JoinColumn(name = "personID")}, 
//inverseJoinColumns = {@JoinColumn(name = "flightID")})

其實這個聲明不是必要的,當我們不用@JoinTable來聲明的時候,JBOSS也會為我們自動生成一個連接用的表,

表名默認是主控端的表名加上下划線"_"再加上反轉端的表名.

類似

@ManyToMany(cascade = CascadeType.ALL)      
@JoinTable(name = "PersonANDFlight", 
        joinColumns = {@JoinColumn(name = "personID")}, 
        inverseJoinColumns = {@JoinColumn(name = "flightID")})      
public List<Flight> getFlights() {
          return flights;     
 }

-----------------------------------------------------

在單向關系中沒有mappedBy,主控方相當於擁有指向另一方的外鍵的一方。
1.一對一和多對一的@JoinColumn注解的都是在“主控方”,都是本表指向外表的外鍵名稱。
2.一對多的@JoinColumn注解在“被控方”,即一的一方,指的是外表中指向本表的外鍵名稱。
3.多對多中,joinColumns寫的都是本表在中間表的外鍵名稱,
  inverseJoinColumns寫的是另一個表在中間表的外鍵名稱。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM