我正在为使用MySQL数据库的EJB3 java应用程序开发一个wicket前端。该网站主要是提交表格和显示表格。对于这些表,我更喜欢创建IDataProviders,它与AjaxPagingNavigation一起使用非常好。但我有一些非常大的表,IDataProvider的大小函数变得有点棘手。通常我使用查询计数,这在大多数情况下表现良好,但我有一些大表,其中计数花费太长时间(3s +)。现在有一些我可以使用的选项,但是我真的不高兴使用其中的任何一个,这就是为什么我问,有没有人知道为大型表实现size()函数的优雅解决方案?
我在Google上找到的第一个选项是使用带有限制结果的子查询来执行计数。但是因为我主要使用命名查询和EJB3,所以感觉很乱,如果发生变化,很难维护。
第二个选项是使用ListDataView,只对表进行有限查询,省略了大量计数查询的需要。到目前为止,这个解决方案是我最喜欢的,但不是最好的,因为它(几乎)总是获得最大量的记录。我还必须在存储此List对象或在请求之间再次查询数据库之间进行选择。
我发现的最后一个选项是欺骗大小选项。我没有实现这个,但我可以让IDataProvider的size()函数返回类似pagesize + 1的东西。这带来了一些其他问题,比如有一个页面化的记录数。有检查来捕捉这些,但这也是凌乱的。
有人知道在wicket中使用IDataProvider显示大型数据库表的分页表的优雅解决方案吗?
非常感谢,马丁
答案 0 :(得分:1)
我已经使用数据提供程序实现了网格视图,该数据提供程序只需要迭代器,没有大小信息 - 称为IterableGridView
以下是代码:https://github.com/maciejmiklas/cyclop/tree/master/cyclop-wicket-components
Iterable Grid View基于Wicket的GridView
,但它不适用于IDataProvider
但是
IterableDataProvider
。这个新的数据提供程序仅依赖于普通的java迭代器 - 不需要大小信息,也不需要为每个页面创建范围迭代器。
final List<String> myGridData = new ArrayList<>();
myGridData.add("value 1");
myGridData.add("value 2");
IterableDataProvider<String> iterableDataProvider = new IterableDataProvider<String>(10) {
@Override
protected Iterator<String> iterator() {
return myGridData.iterator();
}
@Override
public IModel<String> model(String s) {
return Model.of(s);
}
@Override
public void detach() {
}
};
IterableGridView<String> myGrid = new IterableGridView<String>("myGrid", iterableDataProvider) {
@Override
protected void populateEmptyItem(Item<String> item) {
item.add(new Label("myValue"));
}
@Override
protected void populateItem(Item<String> item) {
item.add(new Label("myValue", item.getModelObject()));
}
};
add(myGrid);
myGrid.setItemsPerPage(10);
// you have to use custom pager and not AjaxPagingNavigator
IterablePagingNavigator pager = new IterablePagingNavigator("rowNamesListPager", rowNamesList);
resultTable.add(pager);
答案 1 :(得分:0)
完全放弃分页并使用infinite scrolling实施quickview怎么样?将避免size
的问题,并且列表的使用将更加自然。
答案 2 :(得分:0)
我用&#34;原创&#34;对象系列IDataProvider,似乎很好 - 我自己的JDBC层,有两个重要的功能:
自动执行选择[跳过列]计数(*)...其中...在wicket size()方法下
执行准备(在人的意义上准备)MSSQL查询,哪个服务器 在iterator()下没有LIMIT / OFSET(在旧版本中),我使用ROW_NUMBER()的常用技巧
第二个不是&#39;在你的情况下很重要,因为MySQL有LIMIT / OFFSET
代码是丑陋的,特定于我的集成目标等,但是工作,所以是封闭源代码;)查询是一种&#34;标准&#34;使用字符串替换,相同的标准使用两次。