多对多关系 JPA 与实体
Many To Many Relationship JPA with Entity
我在尝试使用三个实体在 JPA 中生成多重关系时遇到问题。
- 订单
- 产品
- 修改器
我有一个实体来处理多对多关系。
- OrderProducts(order_id 和 product_id)
包含一个订单的关系可以有多个产品
- 订单详情(order_products_id 和 modifier_id)
包含之前关系Order-Products的id和修饰符的Id,修饰符的Id是一组可以影响产品价格的多个值。
不太确定如何在 JPA 中处理这种关系,因为我是新手。
您需要一个带有组合键的连接实体。您需要进一步研究它。
您的实体:
@Entity
@Table(name = "ordertable")
@Data
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "order")
@EqualsAndHashCode.Exclude
private Set<OrderProductModifier> products;
}
@Entity
@Table(name = "product")
@Data
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@EqualsAndHashCode.Exclude
private BigDecimal unitPrice;
}
@Entity
@Table(name = "modifier")
@Data
public class Modifier {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@EqualsAndHashCode.Exclude
private BigDecimal modifier;
}
并且将它们联系在一起的实体将需要具有上述每个实体的外键,正如您所指出的。
@Entity
@Table(name = "orderproductmodifier")
@Data
public class OrderProductModifier {
@EmbeddedId
private OrderProductModifierId id;
@MapsId("orderId")
@ManyToOne
@EqualsAndHashCode.Exclude
@ToString.Exclude
private Order order;
@MapsId("productId")
@ManyToOne
@EqualsAndHashCode.Exclude
private Product product;
@MapsId("modifierId")
@ManyToOne
@EqualsAndHashCode.Exclude
private Modifier modifier;
}
@SuppressWarnings("serial")
@Embeddable
@Data
public class OrderProductModifierId implements Serializable {
private Long orderId;
private Long productId;
private Long modifierId;
}
使用起来非常简单:
private void run() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("UsersDB");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
Product product = new Product();
product.setUnitPrice(BigDecimal.TEN);
em.persist(product);
Modifier modifier = new Modifier();
modifier.setModifier(new BigDecimal(".90"));
em.persist(modifier);
Order order = new Order();
em.persist(order);
OrderProductModifier opm = new OrderProductModifier();
opm.setId(new OrderProductModifierId());
opm.setOrder(order);
opm.setProduct(product);
opm.setModifier(modifier);
em.persist(opm);
em.getTransaction().commit();
em.clear();
Order o = em.createQuery("select o from Order o join fetch o.products where o.id = 1", Order.class).getSingleResult();
System.out.println("Order for " + o.getProducts());
System.out.println("Order cost " + o.getProducts().stream().map(p->p.getProduct().getUnitPrice().multiply(p.getModifier().getModifier()).doubleValue()).collect(Collectors.summingDouble(Double::doubleValue)));
}
上面的查询可能会更好,但这会给你一些工作。
我在尝试使用三个实体在 JPA 中生成多重关系时遇到问题。
- 订单
- 产品
- 修改器
我有一个实体来处理多对多关系。
- OrderProducts(order_id 和 product_id) 包含一个订单的关系可以有多个产品
- 订单详情(order_products_id 和 modifier_id) 包含之前关系Order-Products的id和修饰符的Id,修饰符的Id是一组可以影响产品价格的多个值。
不太确定如何在 JPA 中处理这种关系,因为我是新手。
您需要一个带有组合键的连接实体。您需要进一步研究它。
您的实体:
@Entity
@Table(name = "ordertable")
@Data
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "order")
@EqualsAndHashCode.Exclude
private Set<OrderProductModifier> products;
}
@Entity
@Table(name = "product")
@Data
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@EqualsAndHashCode.Exclude
private BigDecimal unitPrice;
}
@Entity
@Table(name = "modifier")
@Data
public class Modifier {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@EqualsAndHashCode.Exclude
private BigDecimal modifier;
}
并且将它们联系在一起的实体将需要具有上述每个实体的外键,正如您所指出的。
@Entity
@Table(name = "orderproductmodifier")
@Data
public class OrderProductModifier {
@EmbeddedId
private OrderProductModifierId id;
@MapsId("orderId")
@ManyToOne
@EqualsAndHashCode.Exclude
@ToString.Exclude
private Order order;
@MapsId("productId")
@ManyToOne
@EqualsAndHashCode.Exclude
private Product product;
@MapsId("modifierId")
@ManyToOne
@EqualsAndHashCode.Exclude
private Modifier modifier;
}
@SuppressWarnings("serial")
@Embeddable
@Data
public class OrderProductModifierId implements Serializable {
private Long orderId;
private Long productId;
private Long modifierId;
}
使用起来非常简单:
private void run() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("UsersDB");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
Product product = new Product();
product.setUnitPrice(BigDecimal.TEN);
em.persist(product);
Modifier modifier = new Modifier();
modifier.setModifier(new BigDecimal(".90"));
em.persist(modifier);
Order order = new Order();
em.persist(order);
OrderProductModifier opm = new OrderProductModifier();
opm.setId(new OrderProductModifierId());
opm.setOrder(order);
opm.setProduct(product);
opm.setModifier(modifier);
em.persist(opm);
em.getTransaction().commit();
em.clear();
Order o = em.createQuery("select o from Order o join fetch o.products where o.id = 1", Order.class).getSingleResult();
System.out.println("Order for " + o.getProducts());
System.out.println("Order cost " + o.getProducts().stream().map(p->p.getProduct().getUnitPrice().multiply(p.getModifier().getModifier()).doubleValue()).collect(Collectors.summingDouble(Double::doubleValue)));
}
上面的查询可能会更好,但这会给你一些工作。