在DataProvider中使用LoadableDetachableModel的任何目的?

时间:2012-01-08 20:57:08

标签: java wicket wicket-1.5

由于在使用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?

2 个答案:

答案 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)你将恢复数据。

希望有所帮助。