【问题标题】:MapStruct: filter a list before mappingMapStruct:映射前过滤列表
【发布时间】:2019-08-20 19:01:56
【问题描述】:

我在其他地方看到过这个问题,但不是在相同的上下文中,并且没有适合我们用例的答案。

假设我在源对象中有一个列表字段:

List<MySourceElement> mySourceList;

以及对应的目标字段:

List<MyTargetElement> myTargetList;

我只是希望能够在执行 mySourceList 的标准映射器以映射到 myTargetList 之前,通过 MySourceElement 的某些属性过滤源 mySourceList 中的元素。

假设 MySourceElement 有一个布尔属性 isValid,而我们的过滤谓词只是 (isValid == true),而 MyTargetElement 没有对应的布尔值。

我尝试了很多方法,包括@DecoratedWith 和qualifiedBy:

  1. 对于这样一个简单的用例,Guice 注入使@DecoratedWith 变得过于复杂/令人费解,并且此功能也在 MapStruct 文档中列为 jsr330 的实验性功能。

  2. qualifiedBy 不起作用(即,我无法让 mapstruct 在实现中应用qualifiedBy 方法)。

qualifiedBy 方法类似于:

@FilterForValid    
public List<MySourceElement> filterForValid(List<MySourceElement> mySourceElement) {
    ... implementation ...
}

我的映射器声明是这样的:

@Mapping(source = "mySourceList", target = "myTargetList", qualifiedBy = FilterForValid.class)
Target sourceToTarget(Source source);

我想要一个qualifiedBy的实现,比如:

target.withMyTargetList( 
    mySourceListToMyTargetList(filterUtil.filterForValid(source.getMySourceList)));    

代替让qualifiedBy工作,我很乐意弄清楚如何使用@BeforeMapping,但我不清楚我将如何从文档中做到这一点,特别是因为出于所有意图和目的源对象应该被认为是不可变的。

任何有关以这种方式调用映射器的最简单、首选方式进行集合过滤的指导,我们将不胜感激。

【问题讨论】:

    标签: mapstruct


    【解决方案1】:

    有一个请求的功能mapstruct/mapstruct#1610 允许在这里使用开箱即用的支持。话虽如此,解决此问题的方法是使用 @Context 注释。您的映射器可能如下所示:

    @Mapper
    public interface MyMapper {
    
    
        Target map(Source source, @Context Predicate<MySourceElement> predicate);
    
        default List<MySourceElement> mapAndFilter(List<MySourceElement> list, @Context Predicate<MySourceElement> predicate) {
            List<MySourceElement> newList = new ArrayList<>();
            for(MySourceElement el : list) {
                if (predicate.test(el)) {
                    newList.add(map(el));
                }
            }
    
            return newList;
        }
    
        MySourceElement map(MySourceElement el);
    }
    

    【讨论】:

      猜你喜欢
      • 2023-02-22
      • 1970-01-01
      • 2019-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多