Mysql
 sql >> Base de données >  >> RDS >> Mysql

Plusieurs à plusieurs dans la table plusieurs à plusieurs

C'est en fait une bonne question qui mérite quelques recherches et expérimentations. Il existe de nombreuses façons de faire la cartographie. Trouver une meilleure conception dépendrait en fait des besoins de votre application. Mais voici comment je pense que ce serait un moyen efficace d'implémenter le mappage :

J'aurai 3 entités distinctes pour la Order , Product et Address .

Nous n'implémenterons pas la relation habituelle plusieurs à plusieurs entre les 2 entités, Order et Product , où chaque côté a une collection de l'autre. Au lieu de cela, je vais créer une autre entité pour représenter la relation entre Order et Product , et nommons-le ProductOrder . Voici comment leurs relations sont cartographiées :

  • Order a une relation un-à-plusieurs avec ProductOrder .
  • ProductOrder a une relation plusieurs-à-un avec Order .
  • Product a une relation un-à-plusieurs avec ProductOrder .
  • ProductOrder a une relation plusieurs-à-un avec Product .

ProductOrder La clé primaire de sera composée de la clé primaire de Order et la clé primaire de Product - ce sera donc une clé composite. Par conséquent, nous devrons utiliser @IdClass pour mapper des clés composites.

Maintenant, voici l'astuce pour atteindre le plusieurs-à-plusieurs dans une relation plusieurs-à-plusieurs :

ProductOrder a une relation plusieurs-à-plusieurs avec Address .

Voir des exemples de codes pour chaque entité mentionnée ci-dessus :

ENTITÉ DE COMMANDE

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

ENTITÉ PRODUIT

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

ENTITÉ D'ADRESSE

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

ENTITÉ DE COMMANDE DE PRODUIT

@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 pour l'entité ProductOrder

public class ProductOrderId {

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

Voici un exemple de code pour créer les entités et les conserver :

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

Voici comment le schéma a été généré dans la base de données 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)