weblog

技術的なメモ置き場。

【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);

【MapStruct】Expression を使う

Expressionを使うことで、任意のJavaコードをマッピングの際に実行できる。

環境

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

Mapperの作成

expression に実行したいJavaコードを記述する。その際、 java() で囲む。

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

    @Mapping(target = "name", expression = "java(org.springframework.util.StringUtils.capitalize(entity.getName()))")
    Student toStudent(StudentEntity entity);
}

テストコード

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

    Student student = ExpressionMapper.MAPPER.toStudent(entity);

    assertThat(student.getName()).isEqualTo("Curry");
}

expression にパッケージ名から記述したくない場合は、 imports を使用して省略することができる。

@Mapper(imports = StringUtils.class)
public interface ExpressionMapper {

    @Mapping(target = "name", expression = "java(StringUtils.capitalize(entity.getName()))")
    Student toStudent(StudentEntity entity);
}

【MapStruct】デフォルト値と定数を設定する

マッピングする値がnullの場合のデフォルト値と定数の設定ができる。

環境

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

Mapperの作成

デフォルト値は defaultValu, 定数は constant に指定する。

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

    @Mapping(target = "name", defaultValue = "zagas")
    @Mapping(target = "address", constant = "SPOKEN")
    Student toStudent(StudentEntity entity);

}

生成されたコード

/*
@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2018-03-18T22:44:14+0900",
    comments = "version: 1.2.0.Final, compiler: javac, environment: Java 9.0.1 (Oracle Corporation)"
)
*/
public class DefaultConstantsMapperImpl implements DefaultConstantsMapper {

    @Override
    public Student toStudent(StudentEntity entity) {
        if ( entity == null ) {
            return null;
        }

        Student student = new Student();

        if ( entity.getName() != null ) {
            student.setName( entity.getName() );
        }
        else {
            student.setName( "zagas" );
        }
        student.setAge( entity.getAge() );

        student.setAddress( "SPOKEN" );

        return student;
    }
}

テストコード

@Test
public void test() {
    StudentEntity entity = new StudentEntity();

    Student student = DefaultConstantsMapper.MAPPER.toStudent(entity);

    assertThat(student.getName()).isEqualTo("zagas");
    assertThat(student.getAddress()).isEqualTo("SPOKEN");
}