今回は、Jaba Beanマッピングに使用するMapStructを簡単に説明したいと思います。
MapStructとは
設定より規約に基づいてJavaBeanタイプ間のマッピングの実装を大幅に簡素化するコードジェネレーターです。 生成されたマッピングコードはプレーンメソッド呼び出しを使用するため、高速でタイプセーフで理解しやすいものです。
早速簡単に使ってみましょう
依存性追加(Gradle)
dependencies {
...
implementation 'org.mapstruct:mapstruct:1.4.2.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
}
- 上記は正式サイトにある書き方です。
ext {
mapstructVersion = "1.3.1.Final"
}
dependencies {
implementation("org.mapstruct:mapstruct:${mapstructVersion}")
compileOnly "org.mapstruct:mapstruct-processor:${mapstructVersion}"
annotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}"
testAnnotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}"
}
- 上記は自分のプロジェクトに追加した方法です。
Entity作成
public class Car {
private String make;
private int numberOfSeats;
private CarType type;
//constructor, getters, setters etc.
}
DTO作成
public class CarDto {
private String make;
private int seatCount;
private String type;
//constructor, getters, setters etc.
}
マッピングを行うMapperを作成
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); // 2
@Mapping(source = "numberOfSeats", target = "seatCount")
CarDto carToCarDto(Car car); // 3
}
- @Mapperアノテーションは、インターフェイスをマッピングインターフェイスとしてマークし、コンパイル中にMapStructプロセッサを起動できるようにします。
- 実際のマッピングメソッド2は、ソースオブジェクトをパラメータとして想定し、ターゲットオブジェクトを返します。その名前は自由に選ぶことができます。
- インターフェイス実装のインスタンスは、Mappersクラスから取得できます。慣例により、インターフェイスはメンバーINSTANCE 3を宣言し、クライアントにマッパー実装へのアクセスを提供します。
@Mapper(componentModel = "spring")
public interface ProductMapper {
@Mappings({
@Mapping(target = "serviceAddress", ignore = true)
})
Product entityToApi(ProductEntity entity);
@Mappings({
@Mapping(target = "id", ignore = true),
@Mapping(target = "version", ignore = true)
})
ProductEntity apiToEntity(Product api);
}
- 上記は実際に自分がプロジェクトで使った例です。
これで使用までの準備は終わりました。
テスト
@Test
public void shouldMapCarToDto() {
//given
Car car = new Car( "Morris", 5, CarType.SEDAN );
//when
CarDto carDto = CarMapper.INSTANCE.carToCarDto( car );
//then
assertThat( carDto ).isNotNull();
assertThat( carDto.getMake() ).isEqualTo( "Morris" );
assertThat( carDto.getSeatCount() ).isEqualTo( 5 );
assertThat( carDto.getType() ).isEqualTo( "SEDAN" );
}
- Car(Entity)を作成します。
- Mapperインタフェースを使ってEntityからDTOに変換を行います。
- 最後には正常に変換できたのかを確認します。
終わりに
これでMapStructについて簡略に調べてみました。詳細情報は正式のサイトをみていただければと思います。
今まではEntityやDTOに「to」「from」のような変換メソッドを作成してきましたが、詳しく勉強してプロジェクトにも使ってみたいと思います。
