java 多对一_java-多对多表中的多对多

这实际上是一个好问题,值得一些研究和试验.有许多方法可以进行映射.提出更好的设计实际上取决于您的应用程序需求.但是我认为这是实现映射的有效方法:

我将为订单,产品和地址有3个单独的实体.

我们将不会在订单和产品这两个实体之间实现通常的多对多关系,在这两个实体的每一侧都有彼此的集合.相反,我将创建另一个实体来表示Order和Product之间的关系,并将其命名为ProductOrder.它们的关系映射如下:

>订单与ProductOrder具有一对多关系.

> ProductOrder与Order具有多对一关系.

>产品与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();

...

}

生产者实体

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

...

}

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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值