JSF:绝对需要将昂贵的业务逻辑放入访问器方法中。如何避免多次调用这种昂贵的BL

发布于 2024-11-08 03:09:32 字数 1180 浏览 0 评论 0原文

这是我的困境,我知道在 JSF 中访问器方法将被多次调用,因此我知道不要将昂贵的业务逻辑(如数据库访问)放在访问器方法中。如果我绝对必须将业务逻辑放入我的访问器中怎么办?这种情况我该怎么办?以下是我的困境的高级布局。 (Mojarra 2.1,GF 3.1)

<h:dataTable value="#{myBean.comments}" var="item1">
    <h:column>
          #{item1.name} says: #{item1.comment}
          <h:dataTable value="#{myBean.handleReplies(item1)}" var="item2">
               <h:column>
                   #{item2.name} replies: #{item2.comment}
               </h:column>
          </h:dataTable>    
    </h:column>
</h:dataTable>    

@ManagedBean
@ViewScoped
public void myBean(){
    private List<Comment> comments;

    @EJB
    private MyEJB myEJB;

    @PostConstruct
    public void init(){
        comments = myEJB.getAllComments();
    }

    //getters and setters for List<Comment> comments

    public List<Comment> handleReplies(Comment comment){
         //Return a List of replies of the comment
         return myEJB.getRepliesFromComment(comment); 
    }
}

如您所见,inner 数据表采用outer 数据表的item 来生成其列表。有没有办法以某种方式停止 handleReplies() 被多次调用,因为此访问器方法访问数据库。

Here is my dilemma, I know in JSF the accessor method will get call mutilple times, therefore I know not to put expensive business logic (like DB access) in accessor method. What if I absolutely have to put business logic into my accessor. What should I do in this case? Below are a high level layout of my dilemma. (Mojarra 2.1, GF 3.1)

<h:dataTable value="#{myBean.comments}" var="item1">
    <h:column>
          #{item1.name} says: #{item1.comment}
          <h:dataTable value="#{myBean.handleReplies(item1)}" var="item2">
               <h:column>
                   #{item2.name} replies: #{item2.comment}
               </h:column>
          </h:dataTable>    
    </h:column>
</h:dataTable>    

@ManagedBean
@ViewScoped
public void myBean(){
    private List<Comment> comments;

    @EJB
    private MyEJB myEJB;

    @PostConstruct
    public void init(){
        comments = myEJB.getAllComments();
    }

    //getters and setters for List<Comment> comments

    public List<Comment> handleReplies(Comment comment){
         //Return a List of replies of the comment
         return myEJB.getRepliesFromComment(comment); 
    }
}

As you can see, the inner dataTable take in the item of the outer dataTable to generate its List. Is there a way for somehow stop handleReplies() to be called multiple times, since this accessor method access DB.

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

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

发布评论

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

评论(2

讽刺将军 2024-11-15 03:09:32

使用 HashMap 创建视图范围的缓存怎么样?

类似于:

private Map<Comment, List<Comment>> replies = new HashMap<Comment, List<Comment>>();

public List<Comment> handleReplies(Comment comment){
    if (!replies.containsKey(comment)) {
        replies.put(comment, myEJB.getRepliesFromComment(comment));
    }

    return replies.get(comment);
}

这样,您的视图范围 bean 会存储先前的请求结果,并在请求已完成时返回它们。如果没有,则提出请求。最终没有重复请求!

How about using a HashMap to create a view-scoped cache?

Something like:

private Map<Comment, List<Comment>> replies = new HashMap<Comment, List<Comment>>();

public List<Comment> handleReplies(Comment comment){
    if (!replies.containsKey(comment)) {
        replies.put(comment, myEJB.getRepliesFromComment(comment));
    }

    return replies.get(comment);
}

This way, your view-scoped bean store previous request results, and returns them if the request has already been done. If it hasn't, the request is made. In the end, no duplicate request!

迷鸟归林 2024-11-15 03:09:32

您还可以让 JPA 执行延迟加载和缓存工作(使用适当的二级缓存)。

假设您的 Comment 实体如下所示,

@Entity
@NamedQuery(name="Comment.list", query="SELECT c FROM Comment c WHERE c.parent IS NULL")
public class Comment implements Serializable {

    @ManyToOne(optional=false)
    private Comment parent;

    @OneToMany(mappedBy="parent", fetch=LAZY, cascade=ALL);
    private List<Comment> children;

    // ...
}

您可以使用 #{comment.children} 来(懒惰地)获取 中的子级。

You can also just let JPA do the lazy loading and caching job (with a proper second level cache).

Assuming that your Comment entity look like this

@Entity
@NamedQuery(name="Comment.list", query="SELECT c FROM Comment c WHERE c.parent IS NULL")
public class Comment implements Serializable {

    @ManyToOne(optional=false)
    private Comment parent;

    @OneToMany(mappedBy="parent", fetch=LAZY, cascade=ALL);
    private List<Comment> children;

    // ...
}

You could just use #{comment.children} to (lazily) get the children in a <h:dataTable>.

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