weblog

技術的なメモ置き場。

【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...
}

【MapStruct】Mappingを継承する

@InheritConfiguration または @InheritInverseConfiguration を使うことでマッピングを継承することができる。

環境

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

Mapperの作成

@Mapper
public interface PersonMapper {
    PersonMapper MAPPER = Mappers.getMapper(PersonMapper.class);

    @Mapping(target = "emailAddress", source = "email")
    Person toPerson(PersonEntity entity);

    @InheritConfiguration
    Person toPersonInherit(PersonEntity entity);
}

テストコード

    @Test
    public void test() {
        PersonEntity entity = new PersonEntity();
        entity.setEmail("hoge@example.com");
    
        Person person = PersonMapper.MAPPER.toPersonInherit(entity);
    
        assertThat(person.getEmailAddress()).isEqualTo("hoge@example.com");
    }

@InheritInverseConfiguration を使うと、逆向きのマッピングができる。

@Mapper
public interface PersonMapper {
    PersonMapper MAPPER = Mappers.getMapper(PersonMapper.class);

    @Mapping(target = "emailAddress", source = "email")
    Person toPerson(PersonEntity entity);

    @InheritInverseConfiguration
    PersonEntity toPersonInverse(Person person);
}

継承したいマッピングと同様のマッピングが複数定義してある場合は nameマッピングメソッド名を指定する。

@InheritInverseConfiguration(name = "toPerson")
PersonEntity toPersonInverse(Person person);