sql >> Database >  >> RDS >> Mysql

Many to Many binnen Many to Many Table

Dit is eigenlijk een goede vraag die wat onderzoek en experimenteren waard is. Er zijn veel manieren om de mapping uit te voeren. Het bedenken van een beter ontwerp zou eigenlijk afhangen van uw toepassingsbehoeften. Maar hier is hoe ik denk dat een effectieve manier zou zijn om de mapping te implementeren:

Ik heb 3 afzonderlijke entiteiten voor Order , Product en Address .

We zullen niet de gebruikelijke veel-op-veel-relatie tussen de 2 entiteiten implementeren, Order en Product , waar elke kant een verzameling van de andere heeft. In plaats daarvan maak ik een andere entiteit om de relatie tussen Order . weer te geven en Product , en laten we het ProductOrder noemen . Zo worden hun relaties in kaart gebracht:

  • Order heeft een-op-veel relatie met ProductOrder .
  • ProductOrder heeft een veel-op-een relatie met Order .
  • Product heeft een-op-veel relatie met ProductOrder .
  • ProductOrder heeft een veel-op-een relatie met Product .

ProductOrder 's primaire sleutel zal bestaan ​​uit de primaire sleutel van Order en primaire sleutel van Product - dit wordt dus een samengestelde sleutel. Daarom moeten we @IdClass . gebruiken om samengestelde sleutels toe te wijzen.

Dit is de truc om veel-op-veel binnen een veel-op-veel-relatie te bereiken:

ProductOrder heeft een veel-op-veel relatie met Address .

Bekijk voorbeeldcodes voor elke hierboven genoemde entiteit:

ORDERENTITEIT

@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>();
...
}

PRODUCTENTITEIT

@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>();
...
}

ADRESENTITEIT

@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>();
...
}

PRODUCTORDERENTITEIT

@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 voor ProductOrder-entiteit

public class ProductOrderId {

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

Hier is een voorbeeldcode voor het maken van entiteiten en het bewaren ervan:

    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();

Hier is hoe het schema werd gegenereerd in de MySQL-database:

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)



  1. subquery retourneert meer dan 1 rij

  2. PDO-fout:SQLSTATE [HY000]:Algemene fout:2031

  3. Is mysql_insert_id veilig om te gebruiken?

  4. MySQL oplopende waarde