【发布时间】:2021-12-25 08:09:21
【问题描述】:
我正在开发一个库,我希望该库有一个像这样的映射器:
import org.mapstruct.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import spring.graphql.rest.rql.core.nodes.PropertyNode;
import spring.graphql.rest.rql.core.nodes.TraversalMapper;
import spring.graphql.rest.rql.example.dto.AccountDto;
import spring.graphql.rest.rql.example.models.Account;
import java.util.*;
@Mapper(componentModel = "spring", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, uses = {TraversalMapper.class})
public abstract class AccountMapper {
@Autowired
@Qualifier("accountMapperImpl")
protected AccountMapper accountMapper;
@Autowired
protected PostMapper postMapper;
@Autowired
protected PersonMapper personMapper;
@Autowired
protected CommentMapper commentMapper;
@IterableMapping(qualifiedByName = "dynamicAccounts")
public abstract Set<AccountDto> rqlToAccountDtos(Set<Account> entity, @Context StringBuilder currentPath, @Context List<PropertyNode> propertyNodes, @Context List<String> properties, @Context String property);
// TODO: Implement automatic generation/addition of these mappers
@Named("dynamicAccounts")
@Mapping(target = "friends", expression = "java(properties.contains(\"friends\") ? accountMapper.rqlToAccountDtos(entity.getFriends(), currentPath, propertyNodes, properties, \"friends\") : null)")
@Mapping(target = "posts", expression = "java(properties.contains(\"posts\") ? postMapper.toPostDtos(entity.getPosts(), currentPath, propertyNodes, properties, \"posts\") : null)")
@Mapping(target = "comments", expression = "java(properties.contains(\"comments\") ? commentMapper.toCommentDtos(entity.getComments(), currentPath, propertyNodes, properties, \"comments\") : null)")
@Mapping(target = "person", expression = "java(properties.contains(\"person\") ? personMapper.toPersonDto(entity.getPerson(), currentPath, propertyNodes, properties, \"person\") : null)")
public abstract AccountDto rqlToAccountDto(Account entity, @Context StringBuilder currentPath, @Context List<PropertyNode> propertyNodes, @Context List<String> properties, @Context String property);
@Named("dynamicAccountsDefaultCollection")
public Set<AccountDto> toAccountDtosDefault(Collection<Account> entity, @Context List<PropertyNode> propertyNodes) {
return rqlToAccountDtos(new HashSet<>(entity), new StringBuilder(), propertyNodes, new ArrayList<>(), "");
}
@Named("dynamicAccountsDefault")
public AccountDto toAccountDtoDefault(Account entity, @Context List<PropertyNode> propertyNodes) {
return rqlToAccountDto(entity, new StringBuilder(), propertyNodes, new ArrayList<>(), "");
}
}
这意味着内部重新映射。现在,我想添加一个功能,用户可以“覆盖”此方法,例如,他们可以添加一条语句来忽略帐户密码,同时还调用内部方法。
几个例子作为参考点:
import org.mapstruct.*;
import spring.graphql.rest.rql.core.nodes.PropertyNode;
import spring.graphql.rest.rql.example.dto.AccountDto;
import spring.graphql.rest.rql.example.models.Account;
import java.util.List;
@Mapper(componentModel = "spring", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
public abstract class RealAccountMapper extends AccountMapper {
@Mapping(target = "username", ignore = true)
public abstract AccountDto toAccountDtoDefault(Account entity, @Context List<PropertyNode> propertyNodes);
}
@Mapper(componentModel = "spring", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
public abstract class RealAccountMapper {
@Mapping(target = "username", ignore = true)
@Mapper(uses = AccountMapper.class, qualifiedByName = "dynamicAccountsDefault")
public abstract AccountDto toAccountDto(Account entity, @Context List<PropertyNode> propertyNodes);
}
用户应该能够定义一个要忽略的属性,或者例如添加一个指定的源。根据我的实验,即使没有覆盖等,它也只是生成一个单独的映射方法,而不是尝试重用另一个。
这是否可能不需要在用户端实现调用内部方法的自定义方法?如果不是,是否有特殊原因,或者它只是没有作为 MapStruct 中的一个可能功能出现?
【问题讨论】:
标签: java spring spring-boot mapstruct