使用 Dozer 转换嵌套集合

发布于 2025-01-05 23:29:51 字数 617 浏览 0 评论 0原文

我有一个类 A,它有一个类 B 的嵌套集:

public class A {
    private Set<B> children;
}

public class B {
    private int value;
}

我还有一个类 C,它有一个类 D 的嵌套集:

public class C {
    private Set<D> children;
}

public class D {
    private int value;
}

现在给定一个 A 列表,如何将其转换为 C 列表?理想情况下,我不必提供任何映射提示,因为我使用的是泛型。例如:

List<A> src = new ArrayList<A>();
// ----- Add some A's to src -----
List<C> dst = mapper.map(src, List<C>.class);

显然,最后一行的语法不正确。应该是什么?另外,我如何告诉 Dozer 要创建什么类型的列表或集合?

谢谢。

纳雷什

I have a class A which has a nested set of class B:

public class A {
    private Set<B> children;
}

public class B {
    private int value;
}

I also have a class C which has a nested set of class D:

public class C {
    private Set<D> children;
}

public class D {
    private int value;
}

Now given a List of A, how do I convert it to a List of C? Ideally I should not have to supply any mapping hints since I am using generics. For example:

List<A> src = new ArrayList<A>();
// ----- Add some A's to src -----
List<C> dst = mapper.map(src, List<C>.class);

Obviously, the syntax of last line is not correct. What should it be? Also how do I tell Dozer what type of a List or a Set to create?

Thanks.

Naresh

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不回头走下去 2025-01-12 23:29:51

这实际上在他们的常见问题解答中得到了回答,但由于某种原因它一直在高级部分中。我不认为这是一个高级话题,我认为这是一个常见的事情。 您可以使用集合提示来完成此操作。

映射集合时,如何告诉 Dozer 我想要目标集合中的数据对象类型?

支持提示
处理这个用例。如果您使用 JDK 1.5,则不需要提示
泛型是因为 Dozer 可以自动检测类型。但如果你
不使用泛型,将集合/数组转换为
具有不同类型对象的集合/数组,您可以指定提示
让 Dozer 知道您想要在其中创建什么类型的对象
目的地列表。如果没有为目的地指定提示
字段,然后目标集合将填充对象
与 src 集合中的元素类型相同。

<前><代码><字段>
someList
其他列表
org.dozer.vo.TheFirstSubClassPrime

该答案向您展示了如何在 xml 中执行此操作。以下是如何使用映射在 java 代码中完成此操作:

import org.dozer.loader.api.BeanMappingBuilder;

import static org.dozer.loader.api.FieldsMappingOptions.hintB;

public class Mapping extends BeanMappingBuilder {
    @Override
    protected void configure() {
        mapping(Subject.class, JsonSubject.class)
                .fields("names", "names", hintB(JsonName.class));
    }
}

提示告诉 dozer,“这个 A 列表应该转换为 JsonName 实例列表”。以下是将此映射添加到映射器的方法:

    mapper = new DozerBeanMapper();
    mapper.addMapping(new Mapping());

This is actually answered in their FAQ, but it's all the way down in the advanced section for some reason. I don't think this is an advanced topic, I think it's a common thing to want to do. You do it with a collection hint.

When mapping collections, how do I tell Dozer what type of data objects I want in the destination collection?

Hints are supported to
handle this use case. Hints are not required if you are using JDK 1.5
Generics because the types can be auto detected by Dozer. But if you
are not using generics, to convert a Collection/Array to a
Collection/Array with different type objects you can specify a Hint to
let Dozer know what type of objects you want created in the
destination list. If a Hint is not specified for the destination
field, then the destination Collection will be populated with objects
that are the same type as the elements in the src Collection.

<field>
  <a>someList</a>
  <b>otherList</b> 
  <b-hint>org.dozer.vo.TheFirstSubClassPrime</b-hint> 
</field>

That answer shows you how to do it in xml. Here's how you can do it in java code with a Mapping:

import org.dozer.loader.api.BeanMappingBuilder;

import static org.dozer.loader.api.FieldsMappingOptions.hintB;

public class Mapping extends BeanMappingBuilder {
    @Override
    protected void configure() {
        mapping(Subject.class, JsonSubject.class)
                .fields("names", "names", hintB(JsonName.class));
    }
}

The hint tells dozer, "this list of A's should be converted to a list JsonName instances". Here's how you add this mapping to your mapper:

    mapper = new DozerBeanMapper();
    mapper.addMapping(new Mapping());
寄人书 2025-01-12 23:29:51

您应该简单地扩展此列表转换。 Dozer 转换 JavaBean 和此类对象,而不是集合。因此,如果您想传递集合,您可以创建一个包装器,例如

public class EntityConverter {
    private Mapper mapper;

    public EntityConverter(Mapper mapper) {
        this.mapper = mapper;
    }

    public <F, T> List<T> convert(List<F> fromList, final Class<T> toClass) {
        return Lists.transform(fromList, new Function<F, T>() {
            @Override
            public T apply(F from) {
                return convert(from, toClass);
            }
        });
    }

    public <F, T> T convert(F from, final Class<T> toClass) {
        if (from == null) return null;
        return mapper.map(from, toClass);
    }
}

注意:此代码使用 Guava。

You should simply expand this list convertion. Dozer convert JavaBeans and such objects, not collections. So, if you want to pass collections, you can create a wrapper like

public class EntityConverter {
    private Mapper mapper;

    public EntityConverter(Mapper mapper) {
        this.mapper = mapper;
    }

    public <F, T> List<T> convert(List<F> fromList, final Class<T> toClass) {
        return Lists.transform(fromList, new Function<F, T>() {
            @Override
            public T apply(F from) {
                return convert(from, toClass);
            }
        });
    }

    public <F, T> T convert(F from, final Class<T> toClass) {
        if (from == null) return null;
        return mapper.map(from, toClass);
    }
}

Note: This code use Guava.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文