当前位置: 首页 > 知识库问答 >
问题:

带有条件和nullValueProperty tyMappingStrategy的Mapstruct映射

陈俊誉
2023-03-14

如果标题不清楚,我深表歉意,让我给出示例代码:

UpdateProfileDto

public class UpdateProfileDto {

    @NotEmpty
    private String firstName;

    @NotEmpty
    private String lastName;

    @Size(max = 20)
    private String currentPassword;

    @Size(max = 20)
    private String newPassword;

    @Size(max = 20)
    private String confirmNewPassword;

    // getters and setters
}

编码映射

@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface EncodedMapping {
}

密码映射器

public class PasswordEncoderMapper {
    protected final PasswordEncoder passwordEncoder;

    public PasswordEncoderMapper(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    @EncodedMapping
    public String encode(String value) {
        return passwordEncoder.encode(value);
    }
}

用户映射器

@Mapper(config = MapperConfig.class, componentModel = "spring", uses = PasswordEncoderMapper.class)
public interface UserMapper {

    @Mappings({
            @Mapping(target = "firstName", source = "firstName"),
            @Mapping(target = "lastName", source = "lastName"),
            @Mapping(target = "fullName", expression = "java(user.getFirstName() + \" \" + user.getLastName())"),
            @Mapping(target = "password",
                    source = "newPassword",
                    nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE,
                    qualifiedBy = EncodedMapping.class)
    })
    void updateUserFromDto(UpdateUserProfileDto updateUserProfileDto, @MappingTarget User user);
}

生成的UserMapperImpl

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-03-11T13:51:34+0800",
    comments = "version: 1.3.0.Final, compiler: javac, environment: Java 1.8.0_231 (Oracle Corporation)"
)
@Component
public class UserMapperImpl implements UserMapper {

    @Autowired
    private PasswordEncoderMapper passwordEncoderMapper;

    @Override
    public void updateUserFromDto(UpdateUserProfileDto updateUserProfileDto, User user) {
        if ( updateUserProfileDto == null ) {
            return;
        }

        if ( updateUserProfileDto.getFirstName() != null ) {
            user.setFirstName( updateUserProfileDto.getFirstName() );
        }
        else {
            user.setFirstName( null );
        }
        if ( updateUserProfileDto.getLastName() != null ) {
            user.setLastName( updateUserProfileDto.getLastName() );
        }
        else {
            user.setLastName( null );
        }
        if ( updateUserProfileDto.getNewPassword() != null ) {
            user.setPassword( passwordEncoderMapper.encode( updateUserProfileDto.getNewPassword() ) );
        }

        user.setFullName( user.getFirstName() + " " + user.getLastName() );
    }
}

从生成的UserMapperImpl,我不仅想检查newPassword是否有值。。。但是要检查currentPasswordnewPassword是否有值,请继续执行user。setPassword()

我的意思是这样的:

...
if ( updateUserProfileDto.getCurrentPassword() != null && updateUserProfileDto.getNewPassword() != null ) {
    user.setPassword( passwordEncoderMapper.encode( updateUserProfileDto.getNewPassword() ) );
}
...

问题

我怎么能改变我的映射接口UserMapper,以便我将检查当前密码newPassword,然后它将设置目标user.password,并且仍然使用PasswordEncoderMapper.encode(密码)

如果我尝试使用表达式而不是source并检查当前密码newPassword是否都有值,然后将user.password设置为newPassword。否则,它不会对user.password使用NullValueProperty tyMappingStrategy做任何事情...但似乎不允许混合表达式NullValueProperty tyMappingStrategy

谢谢

共有1个答案

齐宗清
2023-03-14

我将从以下方法开始

@Mapper(config = MapperConfig.class, componentModel = "spring")
public abstract class UserMapper { // using class instead of interface to be able to inject beans

    @Autowired
    private PasswordEncoderMapper passwordEncoderMapper;

    @Mappings({
            // your non-password mappings
    })
    void updateUserFromDto(UpdateUserProfileDto updateUserProfileDto, @MappingTarget User user);


    @AfterMapping
    void setPassword(UpdateUserProfileDto updateUserProfileDto, @MappingTarget User user) {
        if (updateUserProfileDto.getCurrentPassword() != null && updateUserProfileDto.getNewPassword() != null) {
            user.setPassword(passwordEncoderMapper.encode( updateUserProfileDto.getNewPassword()));
        }
    }
}
 类似资料:
  • 映射器类如下所示:

  • 我有一个映射定义为 其中定义如下: 反向映射是使用处理的。如何为反向映射指定自定义映射?

  • 我试图让Mapstruct注释处理器在Gradle项目中的IntelliJ中工作。 我所做的: > 在我的中配置了Mapstruct注释处理器: 在“构建、执行、部署->构建工具->gradle->runner”下的首选项中选择了“委托IDE构建/运行操作来分级”

  • 我想将字段从映射到类,如果源值为,我想将其转换为基于数据类型的默认值(“”表示字符串,0表示数值类型等)。对于设置值,我不使用常规的setter,而是使用builder(带有protobuf,因此方法的名称为和)。 我的映射器如下所示: 使用此代码生成的映射器实现调用,而不是执行null检查并在source返回时设置默认值。有趣的是,当我向方法添加以下注释时,在实现中出现了空检查。 这是构建器中的

  • 问题内容: 对于似乎很简单的问题,我找不到解决方案。假设有2种实体类: 如何创建一个标准查询以返回包含至少一个满足给定条件(例如b.text =’condition’)的B实体的所有A? 问题答案: 我认为此链接可能很有用:http : //mikedesjardins.net/2008/09/22/hibernate-criteria- subqueries-exists/ 它包含以下有关如何创

  • 在使用MapStruct、Lombock和Spring时,我在Tomcat 9中的应用程序部署中遇到以下错误: 我的spring配置类在包层次结构的根目录中设置包扫描。映射器的实现也是在target/generated-sources下生成的: 我的错误表明Spring找不到实现类,我遗漏了什么?我试图将generated-sources文件夹添加到构建路径并将其包含在包扫描中,但没有成功。