我应该如何以及何时从 JSF dataTable 的数据库加载模型

问题描述 投票:0回答:1

我有一个数据表如下:

<h:dataTable value="#{bean.items}" var="item">

我想用从服务方法获取的数据库中的集合填充它,以便在初始 (GET) 请求期间打开页面时立即显示该集合。我应该什么时候调用服务方法?为什么?

  1. 在页面加载之前调用它。但如何呢?
  2. 在页面加载期间调用它。怎么办?
  3. 在getter方法中调用。但它被调用了多次。
  4. 还有什么吗?
jsf datatable loading getter
1个回答
20
投票

用bean的

@PostConstruct
方法来做。

@Named
@RequestScoped
public class Bean {

    private List<Item> items;

    @Inject
    private ItemService itemService;

    @PostConstruct
    public void init() {
        items = itemService.list();
    }

    public List<Item> getItems() {
        return items;
    }

}

并让

value
引用属性(而不是方法!)。

<h:dataTable value="#{bean.items}" var="item">

@PostConstruct
中,你有一个优势,它是在构建依赖注入之后执行的。因此,如果您使用 EJB 来执行数据库交互任务,那么 @PostConstruct
 肯定是正确的位置,因为注入的依赖项在普通构造函数中尚不可用。此外,当使用使用代理的 bean 管理框架(例如 CDI 
@Named
)时,构造函数可能会或可能不会按照您期望的方式调用。在检查类、生成代理和/或创建代理期间可能会多次调用它。

至少不要

在getter中执行数据库交互工作,除非它是延迟加载并且你真的不能做任何其他事情。也就是说,它将在每次迭代期间被调用。在每次迭代期间调用服务方法效率很低,并且可能会在呈现和回发期间产生“奇怪”的副作用,例如数据库中的旧值似乎仍然保留在模型中,而不是新提交的值。 如果您依赖 GET 请求参数,则使用

<f:viewParam>

<f:viewAction>
代替。另请参阅
为实体创建主从页面、如何链接它们以及选择哪个 bean 范围
如果您想在同一视图(例如 CRUD 表/对话框)上的回发中保留模型(

items

属性),则使 bean

@ViewScoped
,否则模型将不会与视图同步同一模型在其他地方同时编辑。另请参阅
创建主从表和对话框,如何重用同一对话框进行创建和编辑
如果您在模型上使用 JPA 的

@Version

功能,那么您可以捕获

OptimisticLockException
来处理它并显示一条消息,例如“数据已被其他人编辑,请刷新/检查所需的更改是否符合预期” ”。另请参阅
让表示层 (JSF) 处理来自服务层 (EJB) 的业务异常
另请参阅:

© www.soinside.com 2019 - 2024. All rights reserved.