我有一个包含 产品* 列表的表 订单 。对于与特定订单相对应的每个 产品 ,我需要存储一个 地址 列表,在该 地址 中应将单个产品(每个订单基于每个产品)发送到 *
+----------------+------------+ | 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中。如果我的设计正确,请帮助我提供一个代码片段。如何在Java中使用JPA批注来做到这一点
这实际上是一个好问题,值得一些研究和试验。有许多方法可以进行映射。提出更好的设计实际上取决于您的应用程序需求。但是我认为这是实现映射的有效方法:
我有3个独立的实体Order,Product和Address。
Order
Product
Address
我们不会在2个实体Order和之间实现通常的多对多关系Product,因为双方之间都有彼此的集合。相反,我会创造另一个实体代表之间的关系Order,并Product和让我们命名它ProductOrder。它们的关系映射如下:
ProductOrder
ProductOrder的主键将由Order和的主键组成Product-因此这将是一个复合键。因此,我们将需要使用@IdClass映射复合键。
@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<ProductOrder> productOrderList = new ArrayList<ProductOrder>(); ... }
产品实体
@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>(); ... }
地址实体
@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>(); ... }
生产者实体
@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<Address> addressList = new ArrayList<Address>(); ... }
ProductOrder实体的@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)