如何在Spring Roo中建立多对多关系,且关系内包含属性? [英] How to do a many-to-many relationship in spring Roo, with attributes within de relationship?

查看:89
本文介绍了如何在Spring Roo中建立多对多关系,且关系内包含属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究这个主题,还没有找到任何答案.我正在使用spring roo,我想知道是否可以通过这种关系中的属性建立多对多关系.例如,我有两个表雇员"和医疗设备",雇员"可以保留许多设备,并且许多雇员可以保留设备,但是我想存储此保留的日期.

i have been researching on this topic and havent found any answers yet. Im using spring roo and i would like to know if theres a way I can establish a many-to-many relationship with attributes within this relationship. For example i have two tables Employee and MedicalEquipment, Employees can reserve many equipments, and equipment could be reserved by many employee, however i want to store the date this reserve took place.

如果有人可以提供帮助,我将不胜感激.预先感谢!

If some one can help i would appreciate it. Thanks in advance!

推荐答案

  • 为了实现与属性的多对多关系,您需要一个包含附加列的联接表.也就是说,除了Employee和MedicalEquipment外,您还需要第三个EmployeeMedicalEquipment.

    • In order to achieve a many-to-many relationship with attributes, you need a join table which contains the additional columns. That is, besides Employee and MedicalEquipment, you will need a third EmployeeMedicalEquipment.

      关于JPA,您有两个选择:

      Regarding JPA you have two options:

      1. 将联接表映射到中间实体
      2. 将联接表映射到组件集合

    • 前者比较复杂,但是它允许您进行双向导航(因为它是一个实体,因此可以有共享的引用),后者在构建和使用时更简单,但是您不能使用它在实体之间导航(但是,您可以编写查询来检索所需的对象)

      The former is more complicated, but it allowed you to have bidirectional navigation (because it's an entity and hence, can have shared references), the latter is simpler in both building it and using it, but you can't use it to navigate between entities (however, you can write a query to retrieve the objects you need)

      • Roo是代码生成器,但是缺少JPA提供的所有选项,因此您必须编辑Java类和测试类.视图的构建也有一些限制,因此您也需要对其进行编辑.

      就我而言,我需要创建一个中介实体,因为该表属于已存在的旧数据库.

      In my case, I needed to create an intermediary entity because the table belongs to a legacy database that already existed.

      我做了这样的事情:

      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
      

      此外,您需要通过使用构造函数在关联的任一侧管理集合来确保引用完整性.因此,您需要以以下方式编辑该类:

      Furthermore, you need to guarantees referential integrity by managing collections on either side of the association using the constructor. So you need to edit the class in such way:

      @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配置的例子.

      I tried to give you an example of a Roo configuration.

      您可以从Manning的"Java Persistence with Hibernate"的第7.2.3章中找到关于JPA的更好解释.

      You can find a better explanation of the JPA stuff in the book from Manning "Java Persistence with Hibernate", chapter 7.2.3.

      注意:如果使用roo 1.2.1,则计数查询将生成带有"count(id1,id2)"的SQL,并非所有数据库(包括HSQLDB)都支持该SQL.您可以像这样自定义它:

      Note: if you use roo 1.2.1, the count query will generate SQL with "count(id1, id2)", which is not supported by all databases, including HSQLDB. You can customize it like this:

      ...

      -@RooJpaActiveRecord(identifierType = EmployeeMedicalEquipmentId.class, table = "T_Employee_MedicalEquipment")
      +@RooJpaActiveRecord(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();
              }
          }
      

      这篇关于如何在Spring Roo中建立多对多关系,且关系内包含属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆