由于在使用LDM时仍然没有100%清楚,我尝试了一个简单的内存测试。 我使用DataProvider创建了一个DataView,它只创建了一个包含少量100个实体的列表,其中包含一些大数据(long String):
private class HeavyDataProvider implements IDataProvider<HeavyBean> {
@Override
public void detach() {
}
@Override
public Iterator<? extends HeavyBean> iterator(int first, int count) {
List<HeavyBean> l = newArrayList();
for (int i = 0; i < this.size(); i++) {
l.add(new HeavyBean());
}
return l.iterator();
}
@Override
public IModel<HeavyBean> model(HeavyBean heavyBean) {
return new CompoundPropertyModel<HeavyBean>(heavyBean);
}
@Override
public int size() {
return 500;
}
}
使用wicket的DebugBar可以看到这会创建一个大小为5MB的页面。在DataProvider的javadoc中,声明上面模型方法中的模型返回通常是可拆卸的,所以我将此方法更改为:
@Override
public IModel<HeavyBean> model(final HeavyBean heavyBean) {
return new LoadableDetachableModel<HeavyBean>() {
@Override
protected HeavyBean load() {
return heavyBean;
}
};
}
天真地我期待页面大小现在大大减少,因为重型将不再是模型的一部分。实际结果:5MB。由于模型将分离heavyBean,这必然意味着其他东西仍然保留它(DataView?Item?)。
我看到其他示例,其中DataView和DataProvider以类似的方式组合,但对于我来说,目前还不清楚这是什么意思,因为它似乎没有对pageSize / memory使用产生任何影响。
那么,我是否理解/做错了(可能)或者LDM在DataProviders中没用? 边题(对不起),你会在哪种情况下使用LDM?
答案 0 :(得分:2)
您对LDM的实施是完全错误的。它直接引用bean本身,然后返回它。这样,bean将沿着模型序列化,使其完全没有意义。
你应该这样做:
@Override
public IModel<HeavyBean> model(final HeavyBean heavyBean) {
final Integer id = heavyBean.getId();
return new LoadableDetachableModel<HeavyBean>() {
@Override
protected HeavyBean load() {
return ServiceLocator.get(HeavyDao.class).get(id);
}
};
}
如果您使用wicket-ioc
模块,HeavyDao
引用可以注入封闭的页面/组件。
我认为Wicket非常易于使用,但您必须了解Java序列化的基础知识,否则您最终可能会遇到非常臃肿的http会话。
答案 1 :(得分:0)
要使LDM正常工作,您必须在detach()方法中实际分离数据。 LDM旨在与数据库一起使用,您可以在仅使用ID知识的情况下在下一个请求上恢复/加载数据。因此,在detach()中你会丢弃所有数据,但ID(或需要时需要重新输入数据的沃特)和load()(这是正确的吗?现在不能锁定api)你将恢复数据。
希望有所帮助。