sql >> Databáze >  >> RDS >> Mysql

Many to Many uvnitř Many to Many Table

To je vlastně dobrá otázka, která stojí za průzkum a experimentování. Existuje mnoho způsobů, jak provést mapování. Přijít s lepším designem by ve skutečnosti záviselo na potřebách vaší aplikace. Ale zde je návod, jak si myslím, že by byl efektivní způsob implementace mapování:

Budu mít 3 samostatné entity pro Order , Product a Address .

Nebudeme implementovat obvyklý vztah many-to-many mezi 2 entitami, Order a Product , kde každá strana má sbírku té druhé. Místo toho vytvořím jinou entitu, která bude reprezentovat vztah mezi Order a Product , a pojmenujme to ProductOrder . Zde je návod, jak jsou jejich vztahy mapovány:

  • Order má vztah jeden k mnoha s ProductOrder .
  • ProductOrder má vztah mnoho ku jedné s Order .
  • Product má vztah jeden k mnoha s ProductOrder .
  • ProductOrder má vztah mnoho ku jedné s Product .

ProductOrder Primární klíč uživatele se bude skládat z primárního klíče Order a primární klíč Product - takže toto bude složený klíč. Proto budeme muset použít @IdClass k mapování složených klíčů.

Zde je trik, jak dosáhnout vztahu mnoho k mnoha ve vztahu mnoho k mnoha:

ProductOrder má vztah many-to-many s Address .

Viz ukázkové kódy pro každou výše uvedenou entitu:

ENTITA OBJEDNÁVKY

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

PRODUKTOVÁ ENTITY

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

ADRESA ENTITY

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

ENTITA OBJEDNÁVKY PRODUKTU

@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 pro entitu ProductOrder

public class ProductOrderId {

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

Zde je ukázkový kód pro vytváření entit a jejich zachování:

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

Zde je návod, jak bylo schéma vygenerováno v databázi MySQL:

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. Omezení cizího klíče se nezdaří

  2. Nejnovější trendy PostgreSQL:Nejvíce časově náročné úkoly a důležité metriky ke sledování

  3. MySql count() vrátí 0, pokud nebyly nalezeny žádné záznamy

  4. Které ORM bych měl použít pro Node.js a MySQL?