JSF 2 生命周期

发布于 2024-10-25 22:47:53 字数 2110 浏览 1 评论 0原文

我有 BookModel.java 的代码:

@Entity
@Table(name = "BOOK")
@NamedNativeQuery(name = "BookModel.findBookTitle", query = "SELECT @rownum:=@rownum+1 'no', m.title, m.author, REPLACE(SUBSTRING_INDEX(m.content, ' ', 30), '<br>', ' '), m.viewed, m.hashid FROM book m, (SELECT @rownum:=0) r WHERE m.title like 'a%'")
public class BookModel implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MY_SEQ_GEN")
    @Column(name = "id", unique = true, nullable = false)
    private Long id;

    @NotNull
    @Size(min = 1, max = 255)
    @Column(name = "title")
    private String title;

    @NotNull
    @Size(min = 1, max = 255)
    @Column(name = "author")
    private String author;
}   

业务层的 BookService.java:

@Stateless
public class BookService
{
    @SuppressWarnings("unchecked")
    public List<BookModel> getBook() {
       Query query = entityManager.createNamedQuery("BookModel.findBookTitle");
       List<BookModel> result = query.getResultList();
       return result;
    }
 }

表示层的 BookBean.java:

@ManagedBean(name = "BookBean")
@RequestScoped
public class BookBean implements Serializable
{
    @EJB
    private BookService bookService;
    private DataModel<BookModel> book;

    public DataModel<BookModel> getBook() {
       return book;
    }
}   

页面 book.xhtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.prime.com.tr/ui">
    <p:dataTable id="bookList" value="#{BookBean.book}" var="book">
    ...
    </p:dataTable> 
 </html>

我的问题是: 如何限制方法 getBook() BookBean 中只执行一次而不是六次 - 大概是针对 JSF 生命周期的每个阶段。以前有其他人遇到过这个吗?请帮忙。最后一天一直坚持这个,没有成功。

I have this code for BookModel.java:

@Entity
@Table(name = "BOOK")
@NamedNativeQuery(name = "BookModel.findBookTitle", query = "SELECT @rownum:=@rownum+1 'no', m.title, m.author, REPLACE(SUBSTRING_INDEX(m.content, ' ', 30), '<br>', ' '), m.viewed, m.hashid FROM book m, (SELECT @rownum:=0) r WHERE m.title like 'a%'")
public class BookModel implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MY_SEQ_GEN")
    @Column(name = "id", unique = true, nullable = false)
    private Long id;

    @NotNull
    @Size(min = 1, max = 255)
    @Column(name = "title")
    private String title;

    @NotNull
    @Size(min = 1, max = 255)
    @Column(name = "author")
    private String author;
}   

And BookService.java for the business layer:

@Stateless
public class BookService
{
    @SuppressWarnings("unchecked")
    public List<BookModel> getBook() {
       Query query = entityManager.createNamedQuery("BookModel.findBookTitle");
       List<BookModel> result = query.getResultList();
       return result;
    }
 }

And BookBean.java for the presentation layer:

@ManagedBean(name = "BookBean")
@RequestScoped
public class BookBean implements Serializable
{
    @EJB
    private BookService bookService;
    private DataModel<BookModel> book;

    public DataModel<BookModel> getBook() {
       return book;
    }
}   

And the page book.xhtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.prime.com.tr/ui">
    <p:dataTable id="bookList" value="#{BookBean.book}" var="book">
    ...
    </p:dataTable> 
 </html>

My question is: How can I restrict the method getBook() in BookBean to be executed only once instead of six times - presumably for each phase of JSF lifecycle. Has anyone else come across this before? Please help. Have been stuck on this for the last day without any success.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

故乡的云 2024-11-01 22:47:53

那是不可能的。它通常不会造成伤害。 Getter 的作用只是提供对 Bean 属性的访问点,而不是执行某些业务工作。

如果您确实在该托管 bean 方法中调用了 @EJB 的 getBook() 方法(如下所示)

public DataModel<BookModel> getBook() {
   return new ListDataModel<BookModel>(bookService.getBook());
}

,那么这确实会很昂贵,因为它会多次调用数据库作为吸气剂的名称。您希望在 bean 的构造函数或 @PostConstruct 中完成这项工作。

@PostConstruct
public void init() {
    book = new ListDataModel<BookModel>(bookService.getBook());
}

另请参阅:


与以下内容无关具体问题是,方法名称 getBook() 和变量名称 book 并不是真正的自文档化,因为它实际上包含不止一本书。我会使用 getBooks()books 来代替。

That's not possible. It should usually not harm. Getters are solely there to provide access points to bean properties, not to do some business jobs.

If you did call the @EJBs getBook() method inside that managed bean method like follows

public DataModel<BookModel> getBook() {
   return new ListDataModel<BookModel>(bookService.getBook());
}

then this is indeed going to be expensive as it would call the DB that much times as the getter is called. You would like to do the job in the bean's constructor or @PostConstruct instead.

@PostConstruct
public void init() {
    book = new ListDataModel<BookModel>(bookService.getBook());
}

See also:


Unrelated to the concrete problem, the method name getBook() and variable name book is not really self-documenting since it actually contains more than one book. I'd use getBooks() and books instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文