对于锻炼,我需要构建类似以下内容的东西:

对于一门类(class),我需要创建一个由某些审阅线和反馈分数组成的审阅。

此评论对象(唯一实例)需要由客户列表填写。

取决于所针对的类(class),该评价将发生变化(例如,对于一门类(class),评审专线和反馈分数的数量将发生变化)。每个客户可以注册一个以上的类(class),并且每个评论都是针对他的。

现在,如果我想使用JPA将所有内容保存到数据库中,如何查看“审阅”对象(唯一实例)与“客户”之间的关系?

  • 客户可以填写一个或多个他/她需要填写的评论。
  • 许多客户都需要填写某个评论对象(但这是一个具有特定内部版本的评论对象[评论和反馈分数]),并且对于他来说是唯一的。

  • 也许我认为它很复杂,但是构建它的最佳方法是什么?

    最佳答案

    请尝试以下方法:

    我认为它涵盖了您的所有设计要点。

    我正在尝试在您的评论的各行之间阅读,我认为您想实现一个系统,在其中捕获Review的许多“规则”(我想,但是例子可能是评论最多可以是n行,在CustomerReviews获得一定质量之前,必须至少有m Review个)。如果确实如此,我创建了一个ReviewTemplate类:

  • ReviewTemplate将具有您需要的每个值的属性/列。这些属性/列在Review
  • 上重复
  • 用许多行填充ReviewTemplate,然后在Course中创建一行并将其链接到一个ReviewTemplate
  • Course需要Review时,将字段从ReviewTemplate复制到Review
  • 在Java中,使用复制的值(而不是Review上的值)实现ReviewTemplate的业务规则。

  • 为什么要复制值?好吧,我敢打赌,在某些时候,用户希望编辑ReviewTemplate表。如果是这样,使用已编辑的ReviewReviewTemplates对象怎么办?修改后的ReviewTemplate值是否会以某种方式使过去的Reviews无效并破坏您的业务逻辑?否,因为您已将规则值复制到Review,因此过去的Reviews不会更改。

    编辑:特定问题的答案



    我看到每个ReviewTemplate都具有Review的特定“类型”的原型(prototype)值,其中可能只包含默认的reviewLine(但可能没有意义)和默认的feedbackScore。创建Review时,您将执行以下操作:
  • 实例化Review并使用ReviewTemplate中的值填充
  • 实例化所需数量的CustomerReview对象,并将它们链接到相关的Customer对象(我从您先前的评论中推断出此步骤。在省略Customer自愿选择查看Course之前,也可以省略此步骤)
  • (如果适用),使用CustomerReview的默认值feedbackScore属性ReviewTemplate填充
  • 适当地实例化CustomerReviewLine记录

  • 如果您采用这种方法,则无需在ReviewTemplateCustomerReviewLines之间添加关系。



    绝对地。



    JPA允许您以多种方式来解决问题,但是最佳实践是手动创建数据库模式和Java类(例如,参见https://stackoverflow.com/a/2585763/1395668)。因此,对于图中的每个实体,您需要:
  • 编写SQL DDL语句以创建表,列,主键和外键以及
  • 编写一个用@entity注释表示的Java类。在该类中,您还需要使用@id注释id(主键),并使用@OneToMany@ManyToOne(它们在注释中的其他参数也要设置)来注释关系。

  • 现在,在JPA方面,您可以执行以下操作:
    ReviewTemplate template = course.getReviewTemplate(); //assuming the variable course
    Review review = new Review();
    review.setCourse(course);
    review.setRuleOne(template.getRuleOne());
    // Copy other properties here
    
    EntityManager em = // get the entity manager here
    em.persist(review);
    
    // Assume a set or list of customers
    for (Customer customer : customers) {
        CustomerReview cr = new CustomerReview();
        cr.setReview(review);
        cr.setCustomer(customer);
        cr.setFeedbackScore(template.getDefaultFeedbackScore());
        // set other CustomerReview properties here
    
        em.persist(cr);
    
        // You can create CustomerReviewLine here as well
    

    如果在标准EJB session Bean中编写,则可以很好地进行处理,并且所有新记录都将提交到数据库中。

    编辑2:附加问题

    (我假设第二条评论完全取代了第一条评论)



    我终于认为我了解ReviewLine。我以为是Customer输入包含CustomerReview的文本行的地方。我现在认为ReviewLine是询问Customer的特定问题,并且Customer提供了feedbackScore。

    有了这样的理解,这是一个更新的ER/类图。

    请注意,有一些重大更改-还有更多表:
  • ReviewLineTemplate为模板问题存储在ReviewTemplate上提供了一个位置
  • 实例化/插入Review(这是特定ReviewTemplate的副本)时,该ReviewLineTemplates被复制为ReviewLines。复制操作具有两个重要功能:
  • 创建时,可以自定义Review及其ReviewLines,而不会影响ReviewTemplateReviewLineTemplate
  • 随着时间的推移,可以在不更改ReviewTemplate已经回答的问题的情况下更新,编辑和不断改进ReviewLineTemplateCustomer。如果CustomerFeedbackScore直接链接到ReviewLineTemplate,则编辑ReviewLineTemplate将更改Customer已回答的问题,从而使feedbackScore无效。
  • FeedbackScore已移至ReviewLineCustomerReview之间的联接表。

  • 请注意,此模型已完全非规范化,这使其更“正确”,但更难为其构建GUI。常见的“优化”可能是引入:
  • 关于ReviewTemplateReview的10个(例如)列,称为reviewLine1reviewLine10
  • 通过CustomerReviewfeedbackScore1上的10个列(称为)称为feedbackScore10
  • 删除ReviewTemplateLineReviewLineCustomerReviewLine

  • 这样做是不规范的,并且可能会带来一系列其他问题。青年汽车

    10-07 23:04