【问题标题】:How to map HashMap with Array List of Objects (list is the value in the hash map) into another HashMap using DozerBeanMapper?如何使用 DozerBeanMapper 将带有对象数组列表的 HashMap(列表是哈希映射中的值)映射到另一个 HashMap?
【发布时间】:2019-07-16 00:14:17
【问题描述】:

我有两个类,想使用 org.dozer.Mapper(http://dozer.sourceforge.net/) 将女性对象的属性映射到男性对象。

第一堂课是:

public class Male {
    private String name;
    private String surname;

    private Map<String, List<Contact>> contacts;
....

第二类是:

public class Female {
    private String name;
    private String surname;
    private String mobile;
    private String dateOfBirth;

    private Map<String, List<Contact>> contacts;
...

第三类是:

public class Contact {
    private String street;
    private String postcode;
    private String email;
...

我使用的类似对象属性的 Map 是 LinkedHashMap,而 Map 中的值 List 是 ArrayList。 当我尝试使用推土机对它们进行映射时,作为哈希映射中的值的数组列表不是带有对象的列表,并且如图所示:

        Map<String, List<Contact>> contact = new LinkedHashMap<>();
        List<Contact> listOfContacts = new ArrayList<>();
        Contact contactObj = new Contact();
        contactObj.setEmail("lala@gmail.com");
        contactObj.setPostcode("1233355");
        contactObj.setStreet("street");

        listOfContacts.add(contactObj);

        contact.put("2131323213", listOfContacts);
        femaleObj.setContact(contact);

        Mapper objectMapper = new DozerBeanMapper();
        Male maleObj = objectMapper.map(femaleObj, Male.class);

如何在Male对象的List中获取对象列表?

【问题讨论】:

  • 这是一个非常模糊的问题。您只显示您通过Male maleObj = objectMapper.map(femaleObj, Male.class);female 映射到Male,而没有显示如何 完成;除了LinkedHashMapArrayList 没有出现在您发布的代码中。
  • 我已经编辑了代码,你可以看看
  • 那你的问题是什么?
  • 如何在男性对象的 List 中获取对象列表 - 这没什么意义
  • 包含对象的列表(来自 Contact 类的实例)未正确映射到我的 Male 对象中。您可以从我发布的图片中看到它。

标签: java mapping dozer


【解决方案1】:

起初,我已经按原样尝试了您的代码,并且得到了相同的行为。

然后,我使用 b-hint(参见 documentation about this)显式设置映射配置,如下所示,我得到了您需要的。

第一种情况 - Java 配置(创建一个扩展 BeanMappingBuilder 的类):

public class CustomMapper extends BeanMappingBuilder {
    @Override
    protected void configure() {
        mapping(Female.class, Male.class).fields("contacts", "contacts", FieldsMappingOptions.hintB(Contact.class));
    }
}

第二种情况 - XML 配置

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://dozer.sourceforge.net
          http://dozer.sourceforge.net/schema/beanmapping.xsd">

  <configuration>
    <stop-on-errors>true</stop-on-errors>
    <wildcard>true</wildcard>
  </configuration>

  <mapping>
    <class-a>blog.valerioemanuele.dozer.Female</class-a>
    <class-b>blog.valerioemanuele.dozer.Male</class-b>

      <field>
        <a>contacts</a>
        <b>contacts</b>
        <b-hint>blog.valerioemanuele.dozer.Contact</b-hint> 
      </field>
  </mapping> 


</mappings>

这里是我执行的单元测试:

import org.dozer.DozerBeanMapper;
import org.junit.Assert;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

class TestFemaleToMaleConversion {

    private static Female femaleObj;

    @BeforeAll
    private static void initData() {
        Map<String, List<Contact>> contact = new LinkedHashMap<>();
        List<Contact> listOfContacts = new ArrayList<>();
        Contact contactObj = new Contact();
        contactObj.setEmail("lala@gmail.com");
        contactObj.setPostcode("1233355");
        contactObj.setStreet("street");

        listOfContacts.add(contactObj);

        contact.put("2131323213", listOfContacts);
        femaleObj = new Female();
        femaleObj.setName("Elisabeth");
        femaleObj.setSurname("Chesny");
        femaleObj.setContacts(contact);
    }

    @Test
    void testWithXmlMapping() {
        DozerBeanMapper objectMapper = new DozerBeanMapper();
        objectMapper.setMappingFiles(Arrays.asList("dozer-mapping.xml"));
        Male maleObj = objectMapper.map(femaleObj, Male.class);

        Assert.assertEquals("lala@gmail.com", maleObj.getContacts().get("2131323213").get(0).getEmail());
    }

    @Test
    void testWithJavaMapping() {
        DozerBeanMapper objectMapper = new DozerBeanMapper();
        objectMapper.addMapping(new CustomMapper());
        Male maleObj = objectMapper.map(femaleObj, Male.class);

        Assert.assertEquals("street", maleObj.getContacts().get("2131323213").get(0).getStreet());
    }
}

结果如下:


您可以从my GitHub repository 获取完整代码。该示例使用 Java8、Maven 和 Junit5 开发。

编辑:我添加了 Java 映射配置案例。灵感来自another post

【讨论】:

    【解决方案2】:

    如果你想用 JAVA 代码而不是 XML 配置来达到同样的效果,请使用:

    public class DemoProvider extends BeanMappingBuilder {
    
        @Override
        protected void configure() {
            mapping(Female.class, Male.class,
                    TypeMappingOptions.oneWay()
            )
                    .fields("contact", "contact",
                            FieldsMappingOptions.collectionStrategy(true, RelationshipType.NON_CUMULATIVE),
                            FieldsMappingOptions.hintA(Contact.class),
                            FieldsMappingOptions.hintB(Contact.class),
                            FieldsMappingOptions.oneWay()
                    );
          }
    
    }
    

    用法:

    DemoProvider demoProvider = new DemoProvider();
    DozerBeanMapper objectMapper = new DozerBeanMapper();
    objectMapper.addMapping(demoProvider);
    Male maleObj = objectMapper.map(femaleObj, Male.class);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-13
      • 1970-01-01
      • 2019-01-24
      • 1970-01-01
      • 1970-01-01
      • 2020-12-13
      • 2012-02-29
      相关资源
      最近更新 更多