hibernate單向關系中的JoinColumn詳解


比如 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;
   }
它表示兩張表的關聯是根據兩張表的主鍵的

 

比如person和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 ADD CONSTRAINT person_phone_unique
   UNIQUE (PHONE_id);

ALTER TABLE PERSON_PHONE ADD CONSTRAINT personREFphone
   FOREIGN KEY (PERSON_id) REFERENCES PERSON (id);

ALTER TABLE PERSON_PHONE ADD CONSTRAINT personREFphone2
   FOREIGN KEY (PHONE_id) REFERENCES PHONE (id);

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

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

 

比如person和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所共用的,而一對一卻沒有這一點限制。

比如.person和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