Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Viele zu Viele in der Viele-zu-Viele-Tabelle

Dies ist eigentlich eine gute Frage, die es wert ist, recherchiert und experimentiert zu werden. Es gibt viele Möglichkeiten, das Mapping durchzuführen. Die Entwicklung eines besseren Designs hängt tatsächlich von Ihren Anwendungsanforderungen ab. Aber hier ist, wie ich denke, ein effektiver Weg, um das Mapping zu implementieren:

Ich werde 3 separate Entitäten für Order haben , Product und Address .

Wir werden die übliche Viele-zu-Viele-Beziehung zwischen den beiden Entitäten Order nicht implementieren und Product , wobei jede Seite eine Sammlung der anderen hat. Stattdessen erstelle ich eine andere Entität, um die Beziehung zwischen Order darzustellen und Product , und nennen wir es ProductOrder . So werden ihre Beziehungen abgebildet:

  • Order hat eine Eins-zu-Viele-Beziehung mit ProductOrder .
  • ProductOrder hat eine Viele-zu-Eins-Beziehung mit Order .
  • Product hat eine Eins-zu-Viele-Beziehung mit ProductOrder .
  • ProductOrder hat eine Viele-zu-Eins-Beziehung mit Product .

ProductOrder Der Primärschlüssel von wird aus dem Primärschlüssel von Order bestehen und Primärschlüssel von Product - Dies wird also ein zusammengesetzter Schlüssel sein. Daher müssen wir @IdClass verwenden um zusammengesetzte Schlüssel zuzuordnen.

Nun, hier ist der Trick, um die Viele-zu-Viele-Beziehung innerhalb einer Viele-zu-Viele-Beziehung zu erreichen:

ProductOrder hat eine Viele-zu-Viele-Beziehung mit Address .

Siehe Beispielcodes für jede oben erwähnte Entität:

ORDER ENTITY

@Entity
@Table(name = "ORDERS")
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ORDER_ID")
    private Long id;

    private int quantity;

    @OneToMany(mappedBy = "order")
    private List<ProductOrder> productOrderList = new ArrayList<ProductOrder>();
...
}

PRODUKTENTITÄT

@Entity
@Table(name="PRODUCT")
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "PRODUCT_ID")
    private Long id;

    private String name;

    @OneToMany(mappedBy = "product")
    private List<ProductOrder> productOrderList = new ArrayList<ProductOrder>();
...
}

ADRESSE EINHEIT

@Entity
@Table(name="ADDRESS")
public class Address {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ADDRESS_ID")
    private Long id;

    private String state;

    @ManyToMany(mappedBy = "addressList")
    private List<ProductOrder> productOrderList = new ArrayList<ProductOrder>();
...
}

PRODUCTORDER ENTITY

@Entity
@Table(name="PRODUCT_ORDER")
@IdClass(ProductOrderId.class)
public class ProductOrder {

    @Id
    @ManyToOne
    @JoinColumn(name="ORDER_ID")
    private Order order;

    @Id
    @ManyToOne
    @JoinColumn(name="PRODUCT_ID")
    private Product product;

    @ManyToMany
    @JoinTable(name="PRODUCT_ORDER_ADDRESS",
            joinColumns={@JoinColumn(name="ORDER_ID", referencedColumnName="ORDER_ID"),
                    @JoinColumn(name="PRODUCT_ID", referencedColumnName="PRODUCT_ID")},
            [email protected](name="ADDRESS_ID", referencedColumnName="ADDRESS_ID"))
    private List<Address> addressList = new ArrayList<Address>();
...
}

@IdClass für ProductOrder-Entität

public class ProductOrderId {

    private Long order;
    private Long product;
...
}

Hier ist ein Beispielcode zum Erstellen der Entitäten und zum Beibehalten:

    EntityManager em = emf.createEntityManager();
    em.getTransaction().begin();

    Order order = new Order();
    order.setQuantity(10);
    em.persist(order);

    Product product = new Product();
    product.setName("Coffee");
    em.persist(product);

    Address address = new Address();
    address.setState("CA");
    em.persist(address);

    ProductOrder productOrder = new ProductOrder();
    productOrder.setOrder(order);
    productOrder.setProduct(product);

    productOrder.getAddressList().add(address);
    address.getProductOrderList().add(productOrder);

    em.persist(productOrder);

    em.getTransaction().commit();

So wurde das Schema in der MySQL-Datenbank generiert:

Hibernate: 
    create table ADDRESS (
        ADDRESS_ID bigint not null auto_increment,
        state varchar(255),
        primary key (ADDRESS_ID)
    )
Hibernate: 
    create table ORDERS (
        ORDER_ID bigint not null auto_increment,
        quantity integer not null,
        primary key (ORDER_ID)
    )
Hibernate: 
    create table PRODUCT (
        PRODUCT_ID bigint not null auto_increment,
        name varchar(255),
        primary key (PRODUCT_ID)
    )
Hibernate: 
    create table PRODUCT_ORDER (
        ORDER_ID bigint,
        PRODUCT_ID bigint,
        primary key (ORDER_ID, PRODUCT_ID)
    )
Hibernate: 
    create table PRODUCT_ORDER_ADDRESS (
        ORDER_ID bigint not null,
        PRODUCT_ID bigint not null,
        ADDRESS_ID bigint not null
    )
Hibernate: 
    alter table PRODUCT_ORDER 
        add constraint FK_sl39bwx60xjbvoiujpaes74ty 
        foreign key (ORDER_ID) 
        references ORDERS (ORDER_ID)
Hibernate: 
    alter table PRODUCT_ORDER 
        add constraint FK_n0i7uxq6rxsc0mcred1cds4m9 
        foreign key (PRODUCT_ID) 
        references PRODUCT (PRODUCT_ID)
Hibernate: 
    alter table PRODUCT_ORDER_ADDRESS 
        add constraint FK_kad6crei9lgrv1nuuuff42vs8 
        foreign key (ADDRESS_ID) 
        references ADDRESS (ADDRESS_ID)
Hibernate: 
    alter table PRODUCT_ORDER_ADDRESS 
        add constraint FK_hpx0e467dvpqi5i6kxmujns2b 
        foreign key (ORDER_ID, PRODUCT_ID) 
        references PRODUCT_ORDER (ORDER_ID, PRODUCT_ID)