许多对许多表内多对多
我有一个表订单 ,其中包含产品列表。 对于与特定订单相对应的每个产品 ,我需要存储一个地址列表,其中应将单个产品(按产品每个订单)交付给
+----------------+------------+ | Order_ID | Product_ID | +----------------+------------+ | 1 | 1000 | | 2 | 1000 | | 2 | 1001 | +----------------+------------+
所以我有这个表在订单和产品上的多对多我需要的是将上表中的每个条目映射到地址列表。 所以我需要类似的东西
|PK|Order_ID |Product_ID | | 1| 1 | 1000 | | 2| 2 | 1000 | | 3| 2 | 1001 |
并将上表中的条目映射到地址列表我需要上面的PK和地址ID(我的地址表的主键)上的另外多个表
|PK_Order_Product |Address_ID| | 1 | 1 | | 2 | 1 | | 2 | 3 |
这里PK_Order_Product是上一个表的主键(PK)上的外键我使用JPA来保存到我的MYSQL DB如果我的设计是正确的,请帮我一个代码片段。如何使用JPA注释在Java中执行此操作
这实际上是一个值得进行一些研究和试验的好问题。 有许多方法可以进行映射。 提出更好的设计实际上取决于您的应用需求。 但是我认为这是实现映射的有效方法:
我将为Order
, Product
和Address
分别设置3个实体。
我们不会实现两个实体( Order
和Product
之间通常的多对多关系,其中每个实体都有另一个实体的集合。 相反,我将创建另一个实体来表示Order
和Product
之间的关系,让我们将其命名为ProductOrder
。 以下是他们的关系的映射方式:
-
Order
与ProductOrder
一对多的关系。 -
ProductOrder
与Order
有多对一的关系。 -
Product
与ProductOrder
具有一对多的关系。 -
ProductOrder
与Product
有多对一的关系。
ProductOrder
的主键将由Order
主键和Product
主键组成 – 因此这将是一个复合键。 因此,我们需要使用@IdClass
来映射复合键。
现在,这是在多对多关系中实现多对多的技巧:
ProductOrder
与Address
具有多对多关系。
请参阅上述每个实体的示例代码:
订单实体
@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 productOrderList = new ArrayList (); ... }
产品实体
@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 productOrderList = new ArrayList (); ... }
地址实体
@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 productOrderList = new ArrayList (); ... }
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")}, inverseJoinColumns=@JoinColumn(name="ADDRESS_ID", referencedColumnName="ADDRESS_ID")) private List addressList = new ArrayList(); ... }
ProductIrder实体的@IdClass
public class ProductOrderId { private Long order; private Long product; ... }
以下是用于创建实体并将其持久化的示例代码:
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();
以下是在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)