3

我是 JSF 的新手,想知道我是否做对了。假设我有一个简单的 CMS,可以编写页面。

首先,我定义了一个名为 Page 的 JPA 实体:

@Entity
public class Page {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column
  private Long id;

  @Column private String title;

  @Column private String content;

  // getters & setters ...

}

然后我想在视图中创建Page-s。为此,看起来我需要某种页面 bean。现在我处理了这样的事情:

@Model
public class PageBean {

  private Page page = new Page();

    public String getTitle() {
      return page.getTitle();
    }

    public void setTitle(String title) {
      page.setTitle(title);
    }

    // rest of properties & getters & setters ...

    public void save() {
      // persist using EntityManager
    }
 }

我的问题是以下一个:鉴于我的 JPA 实体模型和我想在视图中使用的模型大部分时间完全相同,有没有办法避免必须在页面豆?

我在某处读到你不应该使用与 JPA 实体和 JSF 模型 bean 相同的 bean(因为 JSF 会重复调用可能影响 JPA 的 getter),但我想知道是否没有更简单的方法可以帮助避免这种代码重复。尤其是当您的应用程序具有大型模型并且在许多情况下不需要视图 bean 中的任何特殊内容时,看起来这会变得非常麻烦。

4

2 回答 2

4

[...] 鉴于我的 JPA 实体模型和我想在视图中使用的模型大部分时间完全相同,有没有办法避免必须在 PageBean 中创建一批 getter 和 setter?

我没有看到在实体周围使用包装器的意义,并且添加这样一个层确实是重复的。只需使用 JSF 页面中的实体。是的,这会在视图和域之间引入某种耦合,但一般来说,修改数据库通常意味着在视图上添加或删除字段。换句话说,我不赞成“解耦”论点,并且我已经编写了足够多的额外层、映射代码、样板代码等,以尽可能支持简单的方法。

我在某处读到您不应该使用与 JPA 实体和 JSF 模型 bean 相同的 bean(因为 JSF 会重复调用可能影响 JPA 的 getter)

如果您可以提供参考,我会很感兴趣,但是如果某处出现问题,包装类(将调用委托给实体)不会改变任何东西。

以防万一,一些额外的资源:

于 2010-07-13T11:18:47.377 回答
2

这不是代码重复。没有重复的算法。业务逻辑仍然在一个地方。

您的 bean 所做的只是将视图连接到域模型。这很好,它是 MVC 模式的一部分。

如果您使用您的 JPA 实体作为您的支持 bean,那么您将打破 MVC 模式。例如,如果有一天String你需要添加一个而不是显示一个纯文本,因为视图需Date要这样做String(即接口要求),你是否要在 JPA 类中编写这个视图逻辑?这没有意义,混合域模型和视图模型。

另一方面,为什么视图必须知道域是如何实现的?如果域值格式发生变化怎么办?(例如,出于性能原因,您在数据库中保存时间戳字符串而不是日期类)。您需要做的只是重写支持 bean 中的方法,它将获取时间戳并将其调整为 Date,以便一切都可以像以前一样工作。在 JPA 类之外只有一个变化。如果你在 JPA 类中拥有它,你最终会在一个类中维护这两种逻辑(接口逻辑和域逻辑)。

如果您想开发一个新视图(例如移动版)怎么办?您要向 JPA 类添加更多代码吗?最好保持 JPA 原样并为移动版本创建另一个 Bean(为两个视图扩展一个公共 bean)。

如果在这一切之后,您仍然不想编写 getter 和 setter,您可以这样做

#{myBean.page.title}

你所需要的只是一个getPage()内部的backing bean。

于 2010-07-13T09:38:32.747 回答