假设我有一个名为 Customer
的实体。可以在应用程序中创建、删除或编辑Customer
对象。
我创建了一个代表 Customer
列表的复合组件,以便我可以在应用程序中的多个位置重用它。
<!-- INTERFACE -->
<cc:interface>
<cc:attribute name="val" required="true"/>
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<p:selectOneMenu value="val">
<f:selectItems value="#{appManager.customers}"
var="cust"
itemLabel="#{cust.name}"/>
</p:selectOneMenu>
</cc:implementation>
此组件使用 EJB 绑定(bind)到 @ApplicationScope
托管 bean。
@Named
@ApplicationScoped
public class AppManager {
@EJB
private CustomerFacade customerFacade;
public AppManager() {
}
public List<Customer> customers(){
return customerFacade.findAll();
}
}
但是每次使用此组件时,都会获取Customer
表,对吗?如何更有效地检索此 Customer
集合?我想到使用集合的延迟加载:
@Named
@ApplicationScoped
public class AppManager {
@EJB
private CustomerFacade customerFacade;
private List<Customer> customers;
/**
* Creates a new instance of AppManager
*/
public AppManager() {
}
public List<Customer> getCustomers() {
if(customers == null){
customers = customerFacade.findAll();
}
return customers;
}
}
但是应用于数据库的更改不会反射(reflect)在集合上。
我非常感谢有关这种情况下的常用技术或最佳实践的建议。谢谢:)
最佳答案
根据情况使用。
如果数据不经常更改,您所做的方式(除了在 @PostConstruct
方法中初始化是明智的事实之外)似乎很好。将其视为初始化应用程序默认值,例如国家列表。您当然可以做一些检查来查看常量是否已自动/手动更改以更新内容。
如果数据不断变化/更新,您获取数据的方式非常低效,因为您不应该在应用程序范围内缓存数据。我能想到的最有效的方法是将数据绑定(bind)到 @ViewScoped
bean 实例和 implement pagination of data如果有很多东西需要(预)加载,或者通过查询参数来完成,就像您的客户情况一样。当然,您可以获取所有数据,以防要加载的项目很少,例如按特定顺序排列的项目列表。
总而言之,我将通过以下方式实现您的解决方案:
- 创建一个 View 作用域 bean,用于保存当前页面数据(客户的子集,例如 20 个)和当前分页状态(当前页面、下一页/上一页/总页数等);
- 能够切换到 View 中的另一个数据子集并相应地更新 Bean 数据;
- 在 EJB 中引入一个新方法,位于
findAll
旁边,例如public List<Customer> find(int from, int to)
.
您也可以通过 <f:param>
进行交流/<f:viewParam>
同时,保持 URL 可添加书签。
关于java - 如何有效地从数据库检索数据以填充 selectonemenu,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19290010/