13

我目前正在使用Dozer将对象映射EntityDto项目中的对象。

我的问题是如何限制内部映射的级别或深度?

例如,我有一个AccountProfile实体,它有一个List<AccountProfileDetail>实体作为成员。此外AccountProfileDetail,它本身有一个FinancialTransLimit实体作为成员。

现在我想告诉映射器,例如仅使用depth = 2. 所以FinancialTransLimit成员不会被复制到AccountProfileDetail目标对象的成员。

我需要使用不在 xml中的编程 API来指定深度。但是,我也没有在 xml 配置中找到它。

我也尝试过Orika,但我在 Orika 中也找不到这样的功能!

以下两个代码(用于使用 Dozer 和 Orika 作为替代进行测试)都可以正常工作并进行深度复制。我需要限制其中至少一个的深度。

请问有人可以帮我吗?

非常感谢!

示例代码:

账户资料

//My Entities:
import java.util.List;

public class AccountProfile{

    private Long id;
    private String name;
    private List<AccountProfileDetail> accountProfileDetails;

    public AccountProfile() {
    }

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<AccountProfileDetail> getAccountProfileDetails() {
        return this.accountProfileDetails;
    }

    public void setAccountProfileDetails(List<AccountProfileDetail> accountProfileDetails) {
        this.accountProfileDetails = accountProfileDetails;
    }
}

账户资料详情

import java.math.BigDecimal;

public class AccountProfileDetail {

    private Long id;
    private BigDecimal accountMinBalance;
    private AccountProfile accountProfile;
    private FinancialTransLimit financialTransLimit;

    public AccountProfileDetail() {
    }

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public BigDecimal getAccountMinBalance() {
        return this.accountMinBalance;
    }

    public void setAccountMinBalance(BigDecimal accountMinBalance) {
        this.accountMinBalance = accountMinBalance;
    }

    public AccountProfile getAccountProfile() {
        return this.accountProfile;
    }

    public void setAccountProfile(AccountProfile accountProfile) {
        this.accountProfile = accountProfile;
    }

    public FinancialTransLimit getFinancialTransLimit() {
        return this.financialTransLimit;
    }

    public void setFinancialTransLimit(FinancialTransLimit financialTransLimit) {
        this.financialTransLimit = financialTransLimit;
    }
}

金融转运

public class FinancialTransLimit{

    private Long id;
    private String limitCode;

    public FinancialTransLimit() {
    }

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getLimitCode() {
        return this.limitCode;
    }

    public void setLimitCode(String limitCode) {
        this.limitCode = limitCode;
    }
}

AccountProfileDto

// My Dtos:
import java.util.List;

public class AccountProfileDto{
    private Long id;
    private String name;
    private List<AccountProfileDetailDto> accountProfileDetails;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public List<AccountProfileDetailDto> getAccountProfileDetails() {
        return accountProfileDetails;
    }

    public void setAccountProfileDetails(List<AccountProfileDetailDto> accountProfileDetails) {
        this.accountProfileDetails = accountProfileDetails;
    }
}

AccountProfileDetailDto

import java.math.BigDecimal;

public class AccountProfileDetailDto {

    private Long id;
    private BigDecimal accountMinBalance;
    private AccountProfileDto accountProfile;
    private FinancialTransLimitDto financialTransLimit;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public BigDecimal getAccountMinBalance() {
        return accountMinBalance;
    }

    public void setAccountMinBalance(BigDecimal accountMinBalance) {
        this.accountMinBalance = accountMinBalance;
    }

    public AccountProfileDto getAccountProfile() {
        return accountProfile;
    }

    public void setAccountProfile(AccountProfileDto accountProfile) {
        this.accountProfile = accountProfile;
    }

    public FinancialTransLimitDto getFinancialTransLimit() {
        return financialTransLimit;
    }

    public void setFinancialTransLimit(FinancialTransLimitDto financialTransLimit) {
        this.financialTransLimit = financialTransLimit;
    }
}

金融交易限额

public class FinancialTransLimitDto {
    private Long id;
    private String limitCode;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getLimitCode() {
        return limitCode;
    }

    public void setLimitCode(String limitCode) {
        this.limitCode = limitCode;
    }
}

现在是Dozer的测试用例代码:

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.dozer.DozerBeanMapper;
import org.dozer.Mapper;


public class TestDozer {

    public static void main(String[] args) {

        List<AccountProfile> profiles = createList();

        Mapper mapper = new DozerBeanMapper();

        List<AccountProfileDto> profileDtos = new ArrayList<AccountProfileDto>(); 

        for (AccountProfile entity: profiles) {
            AccountProfileDto dto = new AccountProfileDto();
            mapper.map(entity, dto);
            profileDtos.add(dto);
        }

        System.out.println(Arrays.deepToString(profileDtos.toArray()));
    }

    private static List<AccountProfile> createList(){
        List<AccountProfile> accountProfiles = new ArrayList<AccountProfile>();

        AccountProfile ap1 = new AccountProfile();
        ap1.setId(new Long(1000));
        ap1.setName("profile1");

        FinancialTransLimit ftlt1 = new FinancialTransLimit();
        ftlt1.setId(new Long(3000));
        ftlt1.setLimitCode("L1");

        AccountProfileDetail apd1 = new AccountProfileDetail();
        apd1.setId(new Long(2000));
        apd1.setAccountProfile(ap1);
        apd1.setAccountMinBalance(new BigDecimal(100000));
        apd1.setFinancialTransLimit(ftlt1);

        List<AccountProfileDetail> apds1 = new ArrayList<AccountProfileDetail>();
        apds1.add(apd1);
        ap1.setAccountProfileDetails(apds1);

        accountProfiles.add(ap1);
        //
        AccountProfile ap2 = new AccountProfile();
        ap2.setId(new Long(1001));
        ap2.setName("profile2");

        FinancialTransLimit ftlt2 = new FinancialTransLimit();
        ftlt2.setId(new Long(3001));
        ftlt2.setLimitCode("L2");

        AccountProfileDetail apd2 = new AccountProfileDetail();
        apd2.setId(new Long(2001));
        apd2.setAccountProfile(ap2);
        apd2.setAccountMinBalance(new BigDecimal(200000));
        apd2.setFinancialTransLimit(ftlt2);

        List<AccountProfileDetail> apds2 = new ArrayList<AccountProfileDetail>();
        apds2.add(apd2);
        ap2.setAccountProfileDetails(apds2);

        accountProfiles.add(ap2);
        //
        return accountProfiles;
    }
}

使用Orika测试代码:

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import ma.glasnost.orika.BoundMapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;

public class TestOrika {

    public static void main(String[] args) {

        List<AccountProfile> profiles = createList();

        MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
        BoundMapperFacade<AccountProfile, AccountProfileDto> mapper = mapperFactory.getMapperFacade(AccountProfile.class, AccountProfileDto.class);

        List<AccountProfileDto> profileDtos = new ArrayList<AccountProfileDto>(); 

        for (AccountProfile entity: profiles) {
            AccountProfileDto dto = new AccountProfileDto();
            mapper.map(entity, dto);
            profileDtos.add(dto);
        }

        System.out.println(Arrays.deepToString(profileDtos.toArray()));
    }

    private static List<AccountProfile> createList(){
        List<AccountProfile> accountProfiles = new ArrayList<AccountProfile>();

        AccountProfile ap1 = new AccountProfile();
        ap1.setId(new Long(1000));
        ap1.setName("profile1");

        FinancialTransLimit ftlt1 = new FinancialTransLimit();
        ftlt1.setId(new Long(3000));
        ftlt1.setLimitCode("L1");

        AccountProfileDetail apd1 = new AccountProfileDetail();
        apd1.setId(new Long(2000));
        apd1.setAccountProfile(ap1);
        apd1.setAccountMinBalance(new BigDecimal(100000));
        apd1.setFinancialTransLimit(ftlt1);

        List<AccountProfileDetail> apds1 = new ArrayList<AccountProfileDetail>();
        apds1.add(apd1);
        ap1.setAccountProfileDetails(apds1);

        accountProfiles.add(ap1);

        //

        AccountProfile ap2 = new AccountProfile();
        ap2.setId(new Long(1001));
        ap2.setName("profile2");

        FinancialTransLimit ftlt2 = new FinancialTransLimit();
        ftlt2.setId(new Long(3001));
        ftlt2.setLimitCode("L2");

        AccountProfileDetail apd2 = new AccountProfileDetail();
        apd2.setId(new Long(2001));
        apd2.setAccountProfile(ap2);
        apd2.setAccountMinBalance(new BigDecimal(200000));
        apd2.setFinancialTransLimit(ftlt2);

        List<AccountProfileDetail> apds2 = new ArrayList<AccountProfileDetail>();
        apds2.add(apd2);
        ap2.setAccountProfileDetails(apds2);

        accountProfiles.add(ap2);

        //

        return accountProfiles;
    }
}
4

1 回答 1

2

我认为这在我使用的最后一个版本(5.5.X)中是不可能的。推土机将尝试将对象从一个映射到另一个,直到他到达终点。如果他找到循环关系,就会抛出异常。此外,如果两个对象具有名称相同的不同类型的属性,则会引发异常。这就是使用第 3 方映射器库的全部意义所在。但是,如果目标对象不包含可以在源映射期间使用的属性,则该属性将被忽略。如果您以不同的方式命名目标属性,理论上应该同样有效。您可以使用这些规则制定一些技巧。

我建议您仅在源对象和目标对象之间没有差异的 1 对 1 映射时才坚持使用 Dozer。如果您对如何映射它有不同或限制,请编写您自己的转换器。

于 2015-11-11T13:04:43.523 回答