2011-09-02 65 views
3

我一直在研究這個主題,還沒有找到任何答案。即時通訊使用春天roo,我想知道是否可以在這種關係中建立與屬性的多對多關係。例如,我有兩張表Employee和MedicalEquipment,員工可以保留許多設備,並且設備可以由許多員工保留,但是我想存儲此保留髮生的日期。如何在spring Roo中實現多對多的關係,以及de關係中的屬性?

如果有人能幫助我將不勝感激。提前致謝!

回答

8
  • 爲了實現與屬性的多對多關係,您需要一個包含附加列的連接表。也就是說,除了員工和醫療設備之外,您還需要第三個員工醫療設備。

  • 關於JPA你有兩種選擇:

    1. 映射連接表到中間實體
    2. 映射連接表到組件的集合

前者是更復雜,但它允許你有雙向導航(因爲它是一個實體,因此可以共享引用),後者在構建它和d使用它,但不能用它在實體間導航(但是,您可以編寫查詢來檢索所需的對象)

  • Roo是一個代碼生成器,但它缺少所有選項JPA提供,所以你必須編輯Java類和測試類。視圖的構建也有一些限制,因此您還需要對其進行編輯。

對我而言,我需要創建一箇中間實體,因爲該表屬於已存在的遺留數據庫。

我做了這樣的事情:

entity --class ~.domain.Employee --table T_Employee [etc...] 
field [etc...] 

entity --class ~.domain.MedicalEquipment --table T_MedicalEquipment [etc...] 
field [etc...] 

entity --class ~.domain.EmployeeMedicalEquipment --table T_Employee_MedicalEquipment --identifierType ~.domain.EmployeeMedicalEquipmentId 
//to store the date this reserve took place. 
field date --fieldName reserveDate --column C_reserveDate [etc...] 

//Bidirectional: you´ll need @JoinColumn insertable = false and updatable = false 
field reference --fieldName employee --type ~.domain.Employee --cardinality MANY_TO_ONE 

//Bidirectional: you'll need @JoinColumn insertable = false and updatable = false 
field reference --fieldName medicalEquipment --type ~.MedicalEquipment --cardinality MANY_TO_ONE 

//Join table's composite primary key 
field string --fieldName employeeId --column employee_ID --class ~.domain.EmployeeMedicalEquipmentId [etc...] 
field string --fieldName medicalEquipmentId --column medicalEquipment_ID --class ~.domain.EmployeeMedicalEquipmentId [etc...] 

//Now, it's time to complete the relationship: 
focus --class ~.domain.Employee 
field set --type ~.domain.EmployeeMedicalEquipment --fieldName medicalEquipments --cardinality ONE_TO_MANY --mappedBy employee 
focus --class ~.domain.MedicalEquipment 
field set --type ~.domain.EmployeeMedicalEquipment --fieldName employees --cardinality ONE_TO_MANY --mappedBy medicalEquipment 

此外,還通過使用構造協會的兩側收藏管理需要保證參照完整性。所以你需要以這種方式編輯類:

@RooEntity(... 
public class EmployeeMedicalEquipment { 

@ManyToOne 
@JoinColumn(name = "employeeId", referencedColumnName = "employeeId", insertable = false, updatable = false) 
private Employee employee; 

@ManyToOne 
@JoinColumn(name="medicalEquipmentId", referencedColumnName="medicalEquipmentId", insertable=false, updatable=false) 
private MedicalEquipment medicalEquipment; 

/** 
* No-arg constructor for JavaBean tools 
*/ 
public EmployeeMedicalEquipment() { 
} 


/** 
* Full constructor, the Employee and MedicalEquipment instances have to have an identifier value, they have to be in detached or persistent state. 
* This constructor takes care of the bidirectional relationship by adding the new instance to the collections on either side of the 
* many-to-many association (added to the collections) 
*/ 
public EmployeeMedicalEquipment(Employee employee, MedicalEquipment medicalEquipment, Date reserveDate) { 
    this.setReserveDate (reserveDate); 

    this.employee = employee; 
    this.medicalEquipment = medicalEquipment; 

    this.setId(new EmployeeMedicalEquipmentId(employee.getId(), medicalEquipment.getId()); 

    // If Employee or MedicalEquipment Guarantee referential integrity 
    employee.getMedicalEquipments().add(this); 
    medicalEquipment.getEmployees().add(this); 
} 
... 

} 

我試着給你一個Roo配置的例子。

你可以找到的東西JPA在本書從曼寧「Java持久性與Hibernate」,章7.2.3一個更好的解釋。

注:如果您使用袋鼠1.2.1,count查詢會產生與 「計數(ID1,ID2)」,這是不是所有的數據庫,包括HSQLDB支持的SQL。您可以自定義它是這樣的:

...

[email protected](identifierType = EmployeeMedicalEquipmentId.class, table = "T_Employee_MedicalEquipment") 
[email protected](identifierType = EmployeeMedicalEquipmentId.class, table = "T_Employee_MedicalEquipment", countMethod="") 
... 
public class EmployeeMedicalEquipment { 
... 
    // count method initially copied from ActiveRecord aspect 
    public static long countEmployeeMedicalEquipments() { 
-  return entityManager().createQuery("SELECT COUNT(o) FROM EmployeeMedicalEquipment o", Long.class).getSingleResult(); 
+  return entityManager().createQuery("SELECT COUNT(o.employee) FROM EmployeeMedicalEquipment o", Long.class).getSingleResult(); 
     } 
    } 
+0

非常感謝你,這是非常有益的。我會看看那本書。我還有另外一個問題,抱歉打擾你太多了,我運行了安全設置命令並對其進行了修改,以便存儲在數據庫中的員工是唯一可以訪問應用程序的人員。現在,任何員工都可以選擇與儲備相關聯的員工,但儲備應該由當時登錄的員工創建,而不是由任何員工創建。你有任何關於如何做到這一點的知識? – Daniel

0

爲什麼你不能有一個單獨的實體來表示你的關係?

只需引入一個名爲MedicalEquipmentReservation的新實體,該實體將包含保留的所有屬性以及員工和醫療設備實體之間的關係。

請看下面的例子。

class MedicalEquipmentReservation{ 
    //attributes 
    Date reservationStartDate;  
    Date reservationEndDate; 

    //relationships 
    Employee employee; 
    Set<Equipment> equipments; //assuming more than one equipment can be borrowed at one reservation 
} 

乾杯和所有與春天Roo最好!

相關問題