Mapstruct:使用合格的 IterableMapping 映射列表属性
Mapstruct: map list properties by use of a qualified IterableMapping
首先,如果这个问题已经提出来了,请允许我道歉。我在 Whosebug 中找不到任何参考资料。
我正在尝试通过 MapStruct 在 bean 之间的映射中使用限定条件,以便通过限定映射在列表之间进行转换。唉,没有成功。
让我们假设我们有以下 classes(尽可能简化,我将省略明显的 getters/setters):
public class A {
private String propertyA;
}
public class B {
private String propertyB;
private A instanceA;
}
public class C {
private List<B> instancesB;
}
public class A1 {
private String propertyA;
}
public class B1 {
private String propertyB;
private A1 instanceA1;
}
public class C1 {
private List<B1> instancesB1;
}
让我们假设有以下限定符:
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface Full{}
我们还假设有以下映射:
@Mapper
public interface MapperA {
A1 toA1(A a);
A toA(A1 a1);
}
@Mapper
public interface MapperB {
B1 toB1(B b);
@Mapping(source="propertyA", target="propertyA1")
@Full
B1 toB1Full(B b);
@IterableMapping(qualifiedBy=Full.class)
@Full
List<B1> toB1s(List<B> bs);
toB(B1 b);
@Mapping(source="propertyA1", target="propertyA")
@Full
toBFull(B1 b);
@IterableMapping(qualifiedBy=Full.class)
@Full
List<B> toBs(List<B1> bs);
}
@Mapper
public interface MapperC {
<HERE IS THE PROBLEM>
}
如何编写 Mapper C 以便对 B 的迭代实例使用完整映射?
不管我怎么写映射的注解,比如
@Mapping(source = "instancesB1", target="instancesB", qualifiedBy=Full.class)
我总是发现自己有一个不完整的映射实体:B1 实例有一个正确映射的 propertyB
字段,但没有 instanceA1
.
我当然可以将 MapperC
写成一个抽象 class,实现方法,手动调用映射器并对此感到满意,但我质疑是否有可能只需以某种方式注释 MapperC
中的方法并让 Mapstruct 自动 为我使用正确的映射方法(因为这是一个过于简单的情况,但我可能有数十个这样的列表要转换).
感谢关注
不确定您是否尝试过,但从示例中看似乎缺少 Mapper#uses
。
在您的情况下,它应该类似于(省略了映射方法):
@Mapper
public interface MapperA {
}
@Mapper(uses = MapperA.class)
public interface MapperB {
}
@Mapper(uses = MapperB.class)
public interface MapperC {
}
当您使用 Mapper#uses
时,MapStruct 将在 uses
中定义的 类 中查找符合条件的方法。但是,如果您没有它,那么 MapStruct 将无能为力,并且会生成一些默认映射。
首先,如果这个问题已经提出来了,请允许我道歉。我在 Whosebug 中找不到任何参考资料。
我正在尝试通过 MapStruct 在 bean 之间的映射中使用限定条件,以便通过限定映射在列表之间进行转换。唉,没有成功。
让我们假设我们有以下 classes(尽可能简化,我将省略明显的 getters/setters):
public class A {
private String propertyA;
}
public class B {
private String propertyB;
private A instanceA;
}
public class C {
private List<B> instancesB;
}
public class A1 {
private String propertyA;
}
public class B1 {
private String propertyB;
private A1 instanceA1;
}
public class C1 {
private List<B1> instancesB1;
}
让我们假设有以下限定符:
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface Full{}
我们还假设有以下映射:
@Mapper
public interface MapperA {
A1 toA1(A a);
A toA(A1 a1);
}
@Mapper
public interface MapperB {
B1 toB1(B b);
@Mapping(source="propertyA", target="propertyA1")
@Full
B1 toB1Full(B b);
@IterableMapping(qualifiedBy=Full.class)
@Full
List<B1> toB1s(List<B> bs);
toB(B1 b);
@Mapping(source="propertyA1", target="propertyA")
@Full
toBFull(B1 b);
@IterableMapping(qualifiedBy=Full.class)
@Full
List<B> toBs(List<B1> bs);
}
@Mapper
public interface MapperC {
<HERE IS THE PROBLEM>
}
如何编写 Mapper C 以便对 B 的迭代实例使用完整映射?
不管我怎么写映射的注解,比如
@Mapping(source = "instancesB1", target="instancesB", qualifiedBy=Full.class)
我总是发现自己有一个不完整的映射实体:B1 实例有一个正确映射的 propertyB
字段,但没有 instanceA1
.
我当然可以将 MapperC
写成一个抽象 class,实现方法,手动调用映射器并对此感到满意,但我质疑是否有可能只需以某种方式注释 MapperC
中的方法并让 Mapstruct 自动 为我使用正确的映射方法(因为这是一个过于简单的情况,但我可能有数十个这样的列表要转换).
感谢关注
不确定您是否尝试过,但从示例中看似乎缺少 Mapper#uses
。
在您的情况下,它应该类似于(省略了映射方法):
@Mapper
public interface MapperA {
}
@Mapper(uses = MapperA.class)
public interface MapperB {
}
@Mapper(uses = MapperB.class)
public interface MapperC {
}
当您使用 Mapper#uses
时,MapStruct 将在 uses
中定义的 类 中查找符合条件的方法。但是,如果您没有它,那么 MapStruct 将无能为力,并且会生成一些默认映射。