当前位置: 首页 > 面试题库 >

多对多表内多对多

微生德运
2023-03-14
问题内容

我有一个包含 产品* 列表的表 订单 。对于与特定订单相对应的每个 产品 ,我需要存储一个 地址 列表,在该 地址
中应将单个产品(每个订单基于每个产品)发送到
*

+----------------+------------+
|    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个独立的实体OrderProductAddress

我们不会在2个实体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<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)


 类似资料:
  • 多对多关联模型 满足条件:一个学生可以选择多个课程,一个课程也可以被多个学生选择 示例: student 学生表 class 课程表 student_has_class 中间表 >[danger] 多对多,需要借助第三个中间表,中间表包含了2个外键,分别是两个表的主键 我们假设有这样的一个场景,文章(Post)可以有多个标签(Tag),同样,一个Tag也可以对应多个Post,我们需要一张关联表Po

  • 问题内容: 有点复杂的问题,但是,基本上我有很多表: 它是和关系的列表。我需要查询以查找word_a和word_b之间的关系是否存在。如果单词可以是单词A或单词b,那么正确的语法是什么? 在我的脑海里 这似乎不起作用,因为我得到了任何一场比赛的结果。有人熟悉这种情况并知道正确的语法吗? 提前致谢。 问题答案: 这应该工作:

  • 问题内容: 假设我有一个数据库,其中包含人员,杂货店和您可以在商店中购买的商品,如下所示: 我还有一个表格可以跟踪哪些商店销售什么: 我还有一张桌子上有购物清单 我的问题是,给定一个人或他们的ID,找出他们可以去的商店的最佳方法是什么,以便他们将所有物品都列入清单。MySQL中是否有针对这些类型的计算的模式? 我的尝试(非常丑陋和凌乱)是这样的: 谢谢你的时间! 使用数据编辑SQL 问题答案: 如

  • 问题内容: 好的,所以这可能是一个琐碎的问题,但是我在可视化和理解差异以及何时使用它们方面遇到困难。对于诸如单向和双向映射之类的概念如何影响一对多/多对多关系,我也还不清楚。我现在正在使用Hibernate,因此任何与ORM相关的解释都将有所帮助。 举例来说,我有以下设置: 那么在这种情况下,我将进行哪种映射?对于这个特定示例的答案肯定会受到赞赏,但我也确实希望获得何时使用一对多和多对多以及何时使

  • 问题内容: 最初,我的数据库中有两个表[Property]和[Employee]。 每个雇员可以有一个“家庭财产”,因此雇员表中有一个“财产”的HomePropertyID FK字段。 后来,我需要对这种情况进行建模,即尽管员工只有一个“房屋财产”,但确实在多个财产上工作或涵盖了多个财产。 因此,我创建了一个[Employee2Property]表,该表具有EmployeeID和PropertyI

  • 在如今的社会,我们非常喜欢给人打上标签,比如 颜值逆天、暖烘烘、高富帅等等。高富帅并不是某一个人的专利,一个人可以被别人打上多个标签,一个标签也可以打在多个人上面。这就是多对多关系。 声明多对多关系需要用到belongsToMany方法。 User.beblongsToMany(Tag, {through: 'user_tag'}); Tag.belongsToMany(User, {throug