【发布时间】:2014-07-11 09:18:26
【问题描述】:
我正在处理一个处理大量数据集的项目。我正在使用 Primefaces 4 和 5、spring 和 hibernate。我必须显示一个非常庞大的数据集,例如最少 3000 行和 100 列具有各种功能,例如排序、过滤、行扩展等。我的问题是,我的应用程序需要 8 到 10 分钟才能显示整个页面以及其他功能(排序、过滤)也需要很多时间。我的客户一点也不高兴。但是我可以为此使用分页,但我的客户又不想分页。所以我决定使用 livescroll,但不幸的是我未能实现 livescroll with lazyload 或 withoutlazyload,因为 PF 中存在有关 livescroll 的错误。我也发布了这个问题here earlier,但没有找到解决方案。
这个性能问题非常关键,对我来说很重要。要显示 3000 行和 100 列,正在加载的页面大小约为 10MB。 我使用 Phase-listener 计算了 JSF 的各种 生命周期 所消耗的时间,我发现它的浏览器正在花时间解析 jsf 呈现的响应.为了完成所有阶段,我的申请只用了 25 秒。 至少我想提高我的项目的性能。请分享任何可以帮助解决此问题的想法、建议和任何内容
注意:getter和setter中没有数据库操作,也没有复杂的业务逻辑。
更新: 这是我没有延迟加载的数据表:
<p:dataTable
style="width:100%"
id="cdTable"
selection="#{controller.selectedArray}"
resizableColumns="true"
draggableColumns="true"
var="cd"
value="#{controller.cdDataModel}"
editable="true"
editMode="cell"
selectionMode="multiple"
rowSelectMode="add"
scrollable="true"
scrollHeight="650"
rowKey="#{cd.id}"
rowIndexVar="rowIndex"
styleClass="screenScrollStyle"
liveScroll="true"
scrollRows="50"
filterEvent="enter"
widgetVar="dt4"
>
这里一切正常,除了过滤。一旦我过滤,就会显示第一页,但无法在数据表上排序或滚动。请注意,我在 Primefaces5 中测试过。
第二次接近
具有相同数据表的延迟加载 1) 当我添加 rows="100" 时,会发生动态滚动,但行编辑、行扩展存在问题,但过滤和排序有效。 2) 当我删除 rows 时,livescroll 可用于行编辑、行扩展等,但过滤和排序不起作用。
我的 LazyLoadModel 如下
public class MyDataModel extends LazyDataModel<YData>
{
@Override
public List<YData> load(int first, int pageSize,
List<SortMeta> multiSortMeta, Map<String, Object> filters) {
System.out.println("multisort wala load");
return super.load(first, pageSize, multiSortMeta, filters);
}
/**
*
*/
private static final long serialVersionUID = 1L;
private List<YData> datasource;
public YieldRecBondDataModel() {
}
public YieldRecBondDataModel(List<YData> datasource) {
this.datasource = datasource;
}
@Override
public YData getRowData(String rowKey) {
// In a real app, a more efficient way like a query by rowKey should be
// implemented to deal with huge data
// List<YData> yList = (List<YData>) getWrappedData();
for (YData y : datasource)
{
System.out.println("datasource :"+datasource.size());
if(y.getId()!=null)
{
if (y.getId()==(new Long(rowKey)))
{
return y;
}
}
}
return null;
}
@Override
public Object getRowKey(YData y) {
return y.getId();
}
@Override
public void setRowIndex(int rowIndex) {
/*
* The following is in ancestor (LazyDataModel):
* this.rowIndex = rowIndex == -1 ? rowIndex : (rowIndex % pageSize);
*/
if (rowIndex == -1 || getPageSize() == 0) {
super.setRowIndex(-1);
}
else
super.setRowIndex(rowIndex % getPageSize());
}
@Override
public List<YData> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters) {
List<YData> data = new ArrayList<YData>();
System.out.println("sort order : "+sortOrder);
//filter
for(YData yInfo : datasource) {
boolean match = true;
for(Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
try {
String filterProperty = it.next();
String filterValue = String.valueOf(filters.get(filterProperty));
Field yField = yInfo.getClass().getDeclaredField(filterProperty);
yField.setAccessible(true);
String fieldValue = String.valueOf(yField.get(yInfo));
if(filterValue == null || fieldValue.startsWith(filterValue)) {
match = true;
}
else {
match = false;
break;
}
} catch(Exception e) {
e.printStackTrace();
match = false;
}
}
if(match) {
data.add(yInfo);
}
}
//sort
if(sortField != null) {
Collections.sort(data, new LazySorter(sortField, sortOrder));
}
int dataSize = data.size();
this.setRowCount(dataSize);
//paginate
if(dataSize > pageSize) {
try {
List<YData> subList = data.subList(first, first + pageSize);
return subList;
}
catch(IndexOutOfBoundsException e) {
return data.subList(first, first + (dataSize % pageSize));
}
}
else
return data;
}
@Override
public int getRowCount() {
// TODO Auto-generated method stub
return super.getRowCount();
}
}
我对这些问题感到厌烦,并成为我的表演终结者。即使我尝试过 Primefaces 5
【问题讨论】:
-
我看不到 100 列适合页面的位置,但无论如何分页是有效的方式(毕竟有一个限制)想象谷歌搜索结果会出现在页面中3000个结果!分页和延迟加载是解决方案,当然也推荐数据库索引。实时滚动问题必须在最新的 5 版本中修复。
-
@HatemAlimam 感谢您的回复,请检查更新。问题是我的客户不想要分页。这就是为什么我必须坚持使用 livescroll,但 livescroll 本身包含错误。
-
延迟加载还有其他问题。您无法在客户端页面中进行搜索。如果您使用服务器端过滤器,则滚动到正确的位置并不容易。 p:dataTable 可以替换为性能更好的 h:dataTable。大表在浏览器客户端的性能方面存在问题。在网络技术中显示大表不是一个好主意!这是桌面应用程序的工作。过滤和分页要好得多。
-
@lada.dvorak...感谢您的建议。但是我的客户不接受分页。所以只剩下一个选项,即livescroll。我几乎搞定了,但过滤不能正常工作。我将尝试使用 h:datatable,除 h:datatable 之外的任何其他方法。
-
也许你可以说服你的客户不使用网络界面进入这个......它似乎更适合桌面应用程序,如果你想坚持使用网络可能是小程序。嘿,如果他只想浏览数据,打开电子表格可能没问题。
标签: jsf-2 primefaces primefaces-extensions