尝试以下方法:
我认为它涵盖了您所有的设计要点。
我正在尝试阅读您的 cmets 的字里行间,并且我认为您想要实现一个系统,您可以在其中为 Review 捕获许多“规则”(我猜,但示例可能是评论最多可以有 n 行,必须至少有 m 个CustomerReviews 才能使Review 获得一定程度的质量)。如果确实如此,我创建了一个ReviewTemplate 类:
-
ReviewTemplate 将为您需要的每个值提供属性/列。这些属性/列在Review 上重复
- 用多行填充
ReviewTemplate,然后在Course 中创建一行并将其链接到一个ReviewTemplate
- 当
Course 需要Review 时,复制字段从ReviewTemplate 到Review
- 在 Java 中,使用 复制的值实现
Review 的业务规则,而不是 ReviewTemplate 上的值。
为什么要复制这些值?好吧,我敢打赌,在某些时候,用户想要编辑ReviewTemplate 表。如果是这样,使用编辑的ReviewTemplates 对Review 对象会发生什么? ReviewTemplate 上的修改值是否会以某种方式使过去的 Reviews 无效并破坏您的业务逻辑?不,因为您将规则值复制到了Review,所以过去的Reviews 不会改变。
编辑:特定问题的答案
您如何看待重复?我可以创建一个具有指定属性的实体 ReviewTemplate。在这个实体中,将有与审查线和反馈分数的关系。
我认为每个ReviewTemplate 都包含Review 的特定“类型”的原型值,其中可能包括默认的reviewLine(但这可能没有意义)和默认的feedbackScore。创建Review 时,您将执行以下操作:
- 实例化
Review 并使用来自 ReviewTemplate 的值填充
-
根据需要实例化尽可能多的 CustomerReview 对象,将它们链接到相关的 Customer 对象(我从您之前的 cmets 推断出这一步。省略这一步也可能有意义,直到 Customer 自愿选择查看Course)
- (如果适用)使用来自
ReviewTemplate 的默认值填充CustomerReview 属性feedbackScore
- 酌情实例化
CustomerReviewLine 记录
如果您遵循此方法,则无需在ReviewTemplate 和CustomerReviewLines 之间添加关系。
当我例如说明客户 1 到 4 需要填写评论 需要创建 4 个特定的“对象”来保存信息,还需要创建 4 组所需的评论线和反馈分数,以便他们都可以保存信息。
绝对的。
我只是不知道如何实现这是一个 JPA 结构,所以信息保存在数据库中......?
JPA 允许您以多种方式解决问题,但最佳实践是手动创建 DB 模式和 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 会话 Bean 中编写,这一切都将得到很好的处理,并且您会将所有新记录提交到数据库中。
编辑 2:附加问题
(我假设第二条评论完全取代了第一条)
因此,当我创建一个评论模板并将其链接到一群客户时,我将模板写入数据库并基于模板创建一堆评论,但链接到特定客户并使用他自己独特的评论线和反馈分数。就像我现在看到的一样,每条评论(模板)的评论线(更多是问题或描述)都是相同的,只是客户之间的分数会发生变化
我终于想明白了ReviewLine。我原以为这是Customer 输入包含CustomerReview 的文本行的地方。我现在相信ReviewLine 是Customer 被问到的一个特定问题,Customer 提供了一个反馈分数。
有了这个理解,这里是一个更新的 ER/Class 图。
请注意,有一些重大变化 - 还有几个表格:
-
ReviewLineTemplate 为模板问题提供了一个存储位置,ReviewTemplate
-
当Review 被实例化/插入(它是特定ReviewTemplate 的副本)时,ReviewLineTemplates 被复制为ReviewLines。复制操作允许两个重要功能:
- 在创建时,可以自定义
Review 及其ReviewLines,而不会影响ReviewTemplate 或ReviewLineTemplate
- 随着时间的推移,
ReviewTemplate 和 ReviewLineTemplate 可以更新、编辑和不断改进,不会更改 Customer 已经回答的问题。如果CustomerFeedbackScore 直接链接到ReviewLineTemplate,那么编辑ReviewLineTemplate 将改变Customer 已回答的问题,默默地使feedbackScore 无效。
FeedbackScore 已移至 ReviewLine 和 CustomerReview 之间的连接表。
请注意,此模型是完全非规范化的,这使得它更“正确”,但更难为其构建 GUI。一个常见的“优化”可能是引入:
-
ReviewTemplate 和 Review 上的 10 个(比如说)列称为 reviewLine1 到 reviewLine10。
-
CustomerReview 上的 10 个(比如说)列称为 feedbackScore1 到 feedbackScore10。
- 删除
ReviewTemplateLine、ReviewLine 和CustomerReviewLine 表
这样做没有标准化,并且可能会引入一系列其他问题。 YMMV