posts - 0, comments - 77, trackbacks - 0, articles - 356
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          EJB學(xué)習(xí)日記(13)

          Posted on 2007-09-27 14:26 semovy 閱讀(312) 評(píng)論(0)  編輯  收藏 所屬分類: EJB
          實(shí)體BEAN的七種關(guān)系之---------多對(duì)多雙向
          Many-to-Many Bidirectional Relationship

          一般來說,多對(duì)多的雙向發(fā)生在雙方都持有對(duì)方的很多引用,A可能持有很多個(gè)B,B也可能持有很多個(gè)A,并且A和B之間還要求能夠互相查詢.在現(xiàn)實(shí)中,我們可以用如下的例子來說明這種關(guān)系:

          人和航班,一個(gè)人可以訂很多次航班,可以是訂了今天的,也可以訂明天的,因?yàn)樗ぷ鞣泵?同樣的,一個(gè)航班不可能只為一個(gè)人而開,也可以接受很多個(gè)人的預(yù)訂.并且這種查詢是雙向的,一個(gè)人他可以查詢他訂了多少個(gè)航班,一個(gè)航班也可以查詢它被多少人訂了,這樣才好根據(jù)訂的情況進(jìn)行安排.

          先看看代碼吧.

          還是老樣子,Person類的代碼
          /*
           * Person.java
           *
           * Created on 2007-9-15, 0:11:58
           *
           * To change this template, choose Tools | Templates
           * and open the template in the editor.
           
          */

          package lbf.entitybean.test1;

          import java.io.Serializable;
          import java.util.List;
          import javax.persistence.CascadeType;
          import javax.persistence.Entity;
          import javax.persistence.GeneratedValue;
          import javax.persistence.GenerationType;
          import javax.persistence.Id;
          import javax.persistence.JoinColumn;
          import javax.persistence.JoinTable;
          import javax.persistence.ManyToMany;
          import javax.persistence.ManyToOne;
          import javax.persistence.OneToMany;
          import javax.persistence.OneToOne;

          /**
           *
           * 
          @author Admin
           
          */
          @Entity
          public class Person implements Serializable {

              
          private static final long serialVersionUID = 1L;
              
          private Long id;
              
          private String name;
              
          private String sex;
              
          private int age;
              
          private Address address;
              
          private List<Phone> phones;
              
          private IDCard idCard;
              
          private Country country;
              
          private List<Car> cars;
              
          private List<Flight> flights;

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

              
          public void setFlights(List<Flight> flights) {
                  
          this.flights = flights;
              }

              @OneToMany(cascade 
          = CascadeType.ALL, mappedBy = "person")
              
          public List<Car> getCars() {
                  
          return cars;
              }

              
          public void setCars(List<Car> cars) {
                  
          this.cars = cars;
              }

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

              
          public void setCountry(Country country) {
                  
          this.country = country;
              }

              @OneToOne(cascade 
          = CascadeType.ALL)
              
          public IDCard getIdCard() {
                  
          return idCard;
              }

              
          public void setIdCard(IDCard idCard) {
                  
          this.idCard = idCard;
              }

              @OneToMany(cascade 
          = CascadeType.ALL)
              @JoinColumn(name 
          = "personID")
              
          public List<Phone> getPhones() {
                  
          return phones;
              }

              
          public void setPhones(List<Phone> phones) {
                  
          this.phones = phones;
              }

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

              
          public void setAddress(Address address) {
                  
          this.address = address;
              }

              
          public int getAge() {
                  
          return age;
              }

              
          public void setAge(int age) {
                  
          this.age = age;
              }

              
          public String getName() {
                  
          return name;
              }

              
          public void setName(String name) {
                  
          this.name = name;
              }

              
          public String getSex() {
                  
          return sex;
              }

              
          public void setSex(String sex) {
                  
          this.sex = sex;
              }

              
          public void setId(Long id) {
                  
          this.id = id;
              }

              @Id
              @GeneratedValue(strategy 
          = GenerationType.AUTO)
              
          public Long getId() {
                  
          return id;
              }
          }

           代表航班的Flight類的代碼:
          /*
           * Flight.java
           * 
           * Created on 2007-9-24, 14:35:45
           * 
           * To change this template, choose Tools | Templates
           * and open the template in the editor.
           
          */

          package lbf.entitybean.test1;

          import java.io.Serializable;
          import java.util.Date;
          import java.util.List;
          import javax.persistence.Entity;
          import javax.persistence.GeneratedValue;
          import javax.persistence.GenerationType;
          import javax.persistence.Id;
          import javax.persistence.ManyToMany;
          import javax.persistence.Temporal;

          /**
           *
           * 
          @author hadeslee
           
          */
          @Entity
          public class Flight implements Serializable {
              
          private static final long serialVersionUID = 1L;
              
          private Long id;

              @Temporal(javax.persistence.TemporalType.TIME)
              
          public Date getArriveTime() {
                  
          return arriveTime;
              }

              
          public void setArriveTime(Date arriveTime) {
                  
          this.arriveTime = arriveTime;
              }

              
          public String getFlightNumber() {
                  
          return flightNumber;
              }

              
          public void setFlightNumber(String flightNumber) {
                  
          this.flightNumber = flightNumber;
              }

              
          public String getFromCity() {
                  
          return fromCity;
              }

              
          public void setFromCity(String fromCity) {
                  
          this.fromCity = fromCity;
              }

              @Temporal(javax.persistence.TemporalType.TIME)
              
          public Date getLeaveTime() {
                  
          return leaveTime;
              }

              
          public void setLeaveTime(Date leaveTime) {
                  
          this.leaveTime = leaveTime;
              }
              @ManyToMany(mappedBy
          ="flights")
              
          public List<Person> getPersons() {
                  
          return persons;
              }

              
          public void setPersons(List<Person> persons) {
                  
          this.persons = persons;
              }

              
          public String getToCity() {
                  
          return toCity;
              }

              
          public void setToCity(String toCity) {
                  
          this.toCity = toCity;
              }
              
          private String flightNumber;
              
          private String fromCity,toCity;
              
          private Date leaveTime,arriveTime;
              
          private List<Person> persons;
              
              
          public void setId(Long id) {
                  
          this.id = id;
              }

              @Id
              @GeneratedValue(strategy 
          = GenerationType.AUTO)
              
          public Long getId() {
                  
          return id;
              }

          }

          我們?cè)賮砜匆豢碝anyToMany的聲明
          public @interface ManyToMany
          {
             Class targetEntity( ) 
          default void.class;
             CascadeType[] cascade( ) 
          default {};
             FetchType fetch( ) 
          default LAZY;
             String mappedBy( ) 
          default "";
          }

          從代碼可以看出,注釋都差不多,只不過多對(duì)多的時(shí)候,僅僅從兩張用外鍵相連是不夠的,必須生成一張用于連接的中間表.也就如下代碼所聲明的地方:
          @ManyToMany(cascade = CascadeType.ALL)
              @JoinTable(name = "PersonANDFlight", joinColumns = {@JoinColumn(name = "personID")}, inverseJoinColumns = {@JoinColumn(name = "flightID")})
              public List<Flight> getFlights() {
                  return flights;
              }

          我們聲明了一張用來連接的表,并且聲明了主控端的列名和反轉(zhuǎn)端的列名,其實(shí)這個(gè)聲明不是必要的,當(dāng)我們不用@JoinTable來聲明的時(shí)候,JBOSS也會(huì)為我們自動(dòng)生成一個(gè)連接用的表,表名默認(rèn)是主控端的表名加上下劃線"_"再加上反轉(zhuǎn)端的表名.

          從上面的注釋我們可以看出,此關(guān)系的主控端在Person這一方,因?yàn)槲覀兛梢栽贔light那一方看到如下注釋:
          @ManyToMany(mappedBy="flights")
              public List<Person> getPersons() {
                  return persons;
              }

          正是因?yàn)殡p向關(guān)系的存在,也由于Person是主控端, 所以Person要取消某次預(yù)定只要remove相應(yīng)的Flight就可以了,而Flight由于是反轉(zhuǎn)端,所以雖然它也可以得到它的所有預(yù)定的人,但是它卻無法改變這種關(guān)系,即使它remove掉了某個(gè)Person,但是這種關(guān)系并不會(huì)在數(shù)據(jù)庫(kù)里面表現(xiàn)出來,因?yàn)楫吘购桨嗍遣荒茈S便取消一個(gè)人的登機(jī)資格的.

          其實(shí)按我的理解來說,多對(duì)多的雙向有點(diǎn)類似于一對(duì)多的單向,只不過雙方都是一對(duì)多,我們這個(gè)例子完全可以用一對(duì)多來實(shí)現(xiàn),但是一對(duì)多實(shí)現(xiàn)的話,就會(huì)有很多重復(fù)的數(shù)據(jù)存在,因?yàn)槊總€(gè)關(guān)系都可能會(huì)有重復(fù)的元素,比如我們這個(gè)例子,如果一對(duì)多的話,每個(gè)航班都會(huì)對(duì)應(yīng)幾百人,哪怕這幾百人下次還坐你的航班,你還要重新定義一下.因?yàn)樯洗蔚膸装偃说耐怄I已經(jīng)指向你了.還要再指向另一個(gè)你,必須要重新生成幾百個(gè)元素,所以在這種情況下,多對(duì)多就可以很好的重用數(shù)據(jù)庫(kù)里面的表了,在Person和Flight表中,都不會(huì)有重復(fù)的元素存在了.并且關(guān)系也明朗了許多.


          主站蜘蛛池模板: 富裕县| 宝应县| 永安市| 德州市| 湟源县| 建宁县| 板桥市| 玉溪市| 晋州市| 衡南县| 隆回县| 北京市| 和平区| 启东市| 双牌县| 泾阳县| 道孚县| 汉源县| 喜德县| 仁布县| 巫山县| 涟水县| 定襄县| 濮阳市| 堆龙德庆县| 朝阳市| 阜新市| 秀山| 舞阳县| 南开区| 上蔡县| 鹿泉市| 济阳县| 乌兰县| 兴宁市| 新竹县| 天镇县| 兖州市| 印江| 深泽县| 黎城县|