weblog@kentama

技術的なメモ置き場。主にJava。

【MapStruct】BeforeMappingとAfterMapping

BeforeMappingとAfterMappingでマッピング前後の処理を追加できる。

環境

  • MapStruct : 1.2.0.Final
  • Java : 9
  • JUnit : 4.12
  • AssertJ : 3.9.1

Mapperの作成

@Mapper
public abstract class PersonMapper {

    @BeforeMapping
    protected void before(PersonEntity entity) {
        entity.setName("BEFORE_" + entity.getName());
    }

    @AfterMapping
    protected void after(@MappingTarget Person person) {
        person.setName(person.getName() + "_AFTER");
    }

    public abstract Person toPerson(PersonEntity entity);
}

生成されたMapper

/*
@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2018-04-02T22:00:38+0900",
    comments = "version: 1.2.0.Final, compiler: javac, environment: Java 9.0.1 (Oracle Corporation)"
)
*/
public class PersonMapperImpl extends PersonMapper {

    @Override
    public Person toPerson(PersonEntity entity) {
        before( entity );

        if ( entity == null ) {
            return null;
        }

        Person person = new Person();

        person.setName( entity.getName() );
        person.setAge( entity.getAge() );

        after( person );

        return person;
    }
}

テストコード

@Test
public void test() {
    PersonEntity entity = new PersonEntity();
    entity.setName("curry");

    PersonMapper mapper = Mappers.getMapper(PersonMapper.class);
    Person person = mapper.toPerson(entity);

    assertThat(person.getName()).isEqualTo("BEFORE_curry_AFTER");
}

【MapStruct】Decoratorを使う

Decoratorを使うことでマッピングをカスタマイズすることができる。

環境

  • MapStruct : 1.2.0.Final
  • Java : 9
  • JUnit : 4.12
  • AssertJ : 3.9.1

Mapperの作成

@DecoratedWith にDecoratorクラスを指定する。

@Mapper
@DecoratedWith(PersonMapperDecorator.class)
public interface PersonMapper {

    PersonMapper MAPPER = Mappers.getMapper(PersonMapper.class);

    Person toPerson(PersonEntity entity);
}

Decoratorの作成

抽象クラスで作成する。 上記で作成したMapperを実装し、任意のメソッドをカスタマイズする。

public abstract class PersonMapperDecorator implements PersonMapper {

    private final PersonMapper delegate;

    public PersonMapperDecorator(PersonMapper delegate) {
        this.delegate = delegate;
    }

    @Override
    public Person toPerson(PersonEntity entity) {
        Person dto = delegate.toPerson(entity);
        dto.setName(dto.getName().toUpperCase());
        return dto;
    }
}

テスト

@Test
public void test() {
    PersonEntity entity = new PersonEntity();
    entity.setName("curry");

    Person person = PersonMapper.MAPPER.toPerson(entity);

    assertThat(person.getName()).isEqualTo("CURRY");
}

【MapStruct】 @MappingConfig で共通設定

@MappingConfig でMapperの共通設定をするConfigクラスを作成できる。

環境

  • MapStruct : 1.2.0.Final
  • Java : 9
  • JUnit : 4.12
  • AssertJ : 3.9.1

Configクラスの作成

@MapperConfig(unmappedTargetPolicy = ReportingPolicy.IGNORE
     , nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL
     , mappingInheritanceStrategy = MappingInheritanceStrategy.AUTO_INHERIT_ALL_FROM_CONFIG)
public interface ShareConfig {

}

Mapperの作成

config 属性に作成したConfigクラスを設定する。

@Mapper(config = ShareConfig.class)
public interface PersonMapper {
    // omit...
}