映射没有源属性的目标属性,同时避免常量和表达式

问题描述 投票:0回答:2

我个人反对用字符串编写 Java 代码。我想要实现的目标是通过表达式 100% 可行。然而,我想尝试找到一种无需这样做的方法。

情况:

TargetJpa {
    ...
    Instant createdAt;
}

我想做的事:

// using 1.5.2.Final
@Mapper(...)
public interface JpaMapper {

    @Mapping(target = "createdAt", qualifiedByName = "now")
    TargetJpa toJpa(Srouce s);

    @Named("now")
    default Instant now() {
        return Instant.now();
    }

}

这显然行不通。它抱怨我缺少来源。这是正确的,我不需要来源,我正在生成一个值。但这不可能是一个常数。我个人希望尽可能少地在字符串中使用 java 代码。

Ofc,有一个明显的解决方法,传递一个虚拟源值。

@Mapper(...)
public interface JpaMapper {

    @Mapping(target = "createdAt", source = "s", qualifiedByName = "now")
    TargetJpa toJpa(Srouce s);

    @Named("now")
    default Instant now(Source s) {
        return Instant.now();
    }

}

但这有一个巨大的缺点。如果我不必命名来源,我可以从这个界面中删除这个“现在”,制作一个“InstantMapper”并重用代码:

@InstantMapper
public class InstantMapperImpl {

    @Now
    default Instant now() {
        return Instant.now();
    }

}

然后将其用在任何东西上:

... uses = { ..., InstantMapperImpl.class }

    ...

    @Mapping(target = "createdAt", qualifiedBy = {InstantMapper.class, Now.class})
    TargetJpa1 toJpa(Srouce1 s);

    @Mapping(target = "createdAt", qualifiedBy = {InstantMapper.class, Now.class})
    TargetJpa2 toJpa(Srouce2 s);

    @Mapping(target = "createdAt", qualifiedBy = {InstantMapper.class, Now.class})
    TargetJpa3 toJpa(Srouce3 s);

有什么方法可以实现这一目标,而不将自己束缚在我根本不需要的某些来源上?

java mapstruct
2个回答
3
投票

MapStruct 目前不支持使用随机方法映射到特定属性。使用

Mapping#target
时,您可以使用几个选项来作为映射源:

  • source
    - 来自特定来源的地图
  • expression
    - 使用表达式进行映射
  • constant
    - 使用一些常量值进行映射
  • ignore
    - 忽略映射

所有其余属性都以一种或另一种方式用于指定映射的其他一些内容。

如果未提供这 4 个选项中的任何一个,则假定

target
中的值是
source
中的值。

例如

@Mapping(target = "createdAt", qualifiedByName = "now")

实际上意味着

@Mapping(target = "createdAt", source = "createdAt", qualifiedByName = "now")

如果您有兴趣在 MapStruct 中看到类似您所请求的内容,我建议您提出 功能请求


0
投票

如果我正确理解了要求,您可以在这种情况下使用表达式。有点笨重,但应该足够了。

@Mapper(...)
public interface JpaMapper {

    @Mapping(target = "createdAt", expression = "java(this.now())")
    TargetJpa toJpa(Srouce s);

    default Instant now() {
        return Instant.now();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.