0

我有一个 index.xhtml

<c:forEach items="${postsBean.homePagePosts}" var="category">
 #{category.name}
 <c:forEach items="#{category.posts}" var="post">
      #{post.postTitle}
      #{post.user.userName}
      #{post.rating}
      #{post.totalReads}
 </c:forEach>
</c:forEach>

一个名为PostsBean.java的托管 bean ,有一个homePagePosts()方法,该方法使用休眠从数据库中获取记录并返回一个列表

public List getHomePagePosts() {
    session = helper.getSessionFactory().openSession();
    session.beginTransaction();
    System.out.println("method called "+ i++ +" times");
    List posts;
    List categoryList = new ArrayList();
    HashMap<String, Object> categoryName = new HashMap<String, Object>();

    String HQL = "from Posts as post where post.category= :category order by post.totalReads desc";
    Query query = session.createQuery(HQL);

    Posts post;
    query.setString("category", TextitConstants.BUSINESS);
    posts = query.list();

    if (!posts.isEmpty()) {
        categoryName.put("name", TextitConstants.BUSINESS);
        categoryName.put("posts", posts);
        categoryList.add(categoryName);
        categoryName = new HashMap<String, Object>();
    }
    query.setString("category", TextitConstants.EDUCATION);
    posts = query.list();
    if (!posts.isEmpty()) {
        categoryName.put("name", TextitConstants.EDUCATION);
        categoryName.put("posts", posts);
        categoryList.add(categoryName);
        categoryName = new HashMap<String, Object>();
    }
    query.setString("category", TextitConstants.ENTERTAINMENT);
    posts = query.list();
    if (!posts.isEmpty()) {
        categoryName.put("name", TextitConstants.ENTERTAINMENT);
        categoryName.put("posts", posts);
        categoryList.add(categoryName);
        categoryName = new HashMap<String, Object>();
    }
    query.setString("category", TextitConstants.HEALTH);
    posts = query.list();
    if (!posts.isEmpty()) {
        categoryName.put("name", TextitConstants.HEALTH);
        categoryName.put("posts", posts);
        categoryList.add(categoryName);
        categoryName = new HashMap<String, Object>();
    }
    query.setString("category", TextitConstants.POLITICS);
    posts = query.list();
    if (!posts.isEmpty()) {
        categoryName.put("name", TextitConstants.POLITICS);
        categoryName.put("posts", posts);
        categoryList.add(categoryName);
        categoryName = new HashMap<String, Object>();
    }
    query.setString("category", TextitConstants.SKILLS);
    posts = query.list();
    if (!posts.isEmpty()) {
        categoryName.put("name", TextitConstants.SKILLS);
        categoryName.put("posts", posts);
        categoryList.add(categoryName);
        categoryName = new HashMap<String, Object>();
    }
    query.setString("category", TextitConstants.TECHNOLOGY);
    posts = query.list();
    if (!posts.isEmpty()) {
        categoryName.put("name", TextitConstants.TECHNOLOGY);
        categoryName.put("posts", posts);
        categoryList.add(categoryName);
        categoryName = new HashMap<String, Object>();
    }
    query.setString("category", TextitConstants.SPORTS);
    posts = query.list();
    if (!posts.isEmpty()) {
        categoryName.put("name", TextitConstants.SPORTS);
        categoryName.put("posts", posts);
        categoryList.add(categoryName);
    }
    return categoryList;
}

问题是在渲染 index.xhtml 页面之前多次调用方法 postsBean.homePagePosts。它应该只被调用一次并将一个列表返回给 forEach 循环,然后 forEach 循环将迭代列表并显示结果......

以下是我发现在表格中运行具有可变数据量的网站的测试结果

  • 5 条记录 = 26 次执行
  • 4 条记录 = 22 次执行
  • 3 条记录 = 16 次执行
  • 2 条记录 = 10 次执行
  • 1 条记录 = 7 次执行
  • 0 条记录 = 1 次执行

可以清楚的看到方法的执行和数据库的记录数没有对称性

需要注意的一件事...我没有在方法 postsBean.homePagePosts() 中关闭 Hibernate 会话,因为如果我这样做了,EL #{post.user.userName}在会话关闭时会出现异常。(post.user 是 User 类的对象)

4

0 回答 0