我目前正在使用 Dozer 将Entity
个对象映射到我项目中的Dto
个对象。
我的问题是如何限制内部映射的级别或深度?
例如,我有一个AccountProfile
实体,其中有List<AccountProfileDetail>
个实体作为成员。此外,AccountProfileDetail
本身有一个FinancialTransLimit
实体作为成员。
现在我想告诉映射器,例如只用depth = 2
进行映射。因此,FinancialTransLimit
成员不会被复制到目标对象的AccountProfileDetail
成员。
我需要在xml中使用Programming API 指定深度。但是,我也没有在xml配置中找到它。
我也尝试过 Orika ,但我也无法在Orika找到这样的功能!
以下两个代码(使用Dozer和Orika作为替代方案进行测试)都可以正常工作并进行深层复制。 我需要限制其中至少一个的深度。
有人可以帮帮我吗?
非常感谢!
示例代码:
AccountProfile
//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;
}
}
AccountProfileDetail
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;
}
}
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;
}
}
FinancialTransLimitDto
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;
}
}
现在使用推土机的测试用例代码:
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;
}
}
答案 0 :(得分:2)
我认为在我使用的最后一个版本(5.5.X)中不可能。推土机会尝试将物体从一个物体映射到另一个物体,直到它到达终点。如果他找到一个循环关系,它将抛出异常。此外,如果两个对象具有名称相同的不同类型的属性,则将抛出异常。这是使用第3方映射器库的重点。 但是,如果目标对象不包含可在源映射期间使用的属性,则只会忽略该属性。如果您以不同方式命名目标属性,理论上应该相同。你可以使用这些规则来解决一些问题。
如果你有1到1个映射,而源和目标对象没有区别,我建议你坚持使用Dozer。如果您对映射方式有不同或限制,请编写自己的转换器。