如果Dto使用MapStruct具有ID,则将dto映射到从数据库检索到的实体

Rad*_*FID 4 java mapping data-transfer-objects mapstruct

我正在使用MapStruct进行dto <-> entity映射。相同的映射器用于从dto 创建 更新实体。完成dto的id验证以了解是否必须创建一个新实体(id == null)还是应该从数据库中检索它(id!= null)。

我实际上正在使用MapperDecorator作为解决方法。范例:

映射器

@Mapper
@DecoratedWith(UserAccountDecorator.class)
public interface UserAccountMapper {

    UserAccountDto map(User user);

    User map(UserAccountDto dto);

    User map(UserAccountDto dto, @MappingTarget User user);
}
Run Code Online (Sandbox Code Playgroud)

装饰器

public abstract class UserAccountDecorator implements UserAccountMapper {

    @Autowired
    @Qualifier("delegate")
    private UserAccountMapper delegate;

    @Autowired
    private UserRepository userRepository;

    @Override
    public User map(UserAccountDto dto) {
        if (dto == null) {
            return null;
        }

        User user = new User();
        if (dto.getId() != null) {
            user = userRepository.findOne(dto.getId());
        }

        return delegate.map(dto, user);
    }

}
Run Code Online (Sandbox Code Playgroud)

但是,由于必须为每个映射器创建一个装饰器,因此该解决方案变得繁重。

有什么好的解决方案吗?


我正在使用 :

  1. MapStruct:1.1.0

Rad*_*FID 5

我按照评论Gunnar的建议解决了我的问题。

我移至MapStruct 1.2.0.Beta1并创建了一个UserMapperResolver,如下所示

@Component
public class UserMapperResolver {

    @Autowired
    private UserRepository userRepository;

    @ObjectFactory
    public User resolve(BaseUserDto dto, @TargetType Class<User> type) {
        return dto != null && dto.getId() != null ? userRepository.findOne(dto.getId()) : new User();
    }

}
Run Code Online (Sandbox Code Playgroud)

然后我在UserMapper中使用它:

@Mapper(uses = { UserMapperResolver.class })
public interface BaseUserMapper {

    BaseUserDto map(User user);

    User map(BaseUserDto baseUser);

}
Run Code Online (Sandbox Code Playgroud)

现在生成的代码是:

@Override
    public User map(BaseUserDto baseUser) {
        if ( baseUser == null ) {
            return null;
        }

        User user = userMapperResolver.resolve( baseUser, User.class );

        user.setId( baseUser.getId() );
        user.setSocialMediaProvider( baseUser.getSocialMediaProvider() );
...
}
Run Code Online (Sandbox Code Playgroud)

效果很好 !