エキサイト株式会社メディア開発の佐々木です。
以前、下記の記事でJavaのオブジェクトマッピングツールでModelMapperを紹介しました。
ModelMapperは、とてもお手軽で大変便利なのですが、やや速度に問題があり大量のデータ処理等には不向きです。そこで MapStructを紹介します。
ライブラリ追加
build.gradleに下記を追加し、ライブラリを追加します。
dependencies { ... implementation 'org.mapstruct:mapstruct:1.4.2.Final' annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final' annotationProcessor 'org.projectlombok:lombok-mapstruct-binding:0.2.0' // lombokを併用する場合は必要 ... }
コード全体
コード全体は下記のようになります。
public class DemoMain { public static void main(String[] args) { InputModel inputModel = new InputModel(); inputModel.setId(1); inputModel.setName("taro"); RequestModel requestModel = RequestMapper.INSTANCE.toRequestModel(inputModel); System.out.println(requestModel); Request2Model request2Model = RequestMapper.INSTANCE.toRequest2Model(inputModel); System.out.println(request2Model); } @Data static class InputModel { private Integer id; private String name; } @Data static class RequestModel { private Integer id; private String name; } @Data static class Request2Model { private Integer no; private String title; } @Mapper interface RequestMapper { RequestMapper INSTANCE = Mappers.getMapper(RequestMapper.class); RequestModel toRequestModel(InputModel inputModel); @Mapping(source = "name", target = "title") @Mapping(source = "id", target = "no") Request2Model toRequest2Model(InputModel inputModel); } }
出力結果
出力結果は下記になります。
DemoMain.RequestModel(id=1, name=taro) DemoMain.Request2Model(no=1, title=taro)
ざっくり解説
データクラス定義
入力のクラスはこのように定義します。
@Data static class InputModel { private Integer id; private String name; }
出力は、プロパティ名が同じものを用意します。異なったものでも可能なので、そのケースものも用意しておきます。
// プロパティが同じクラス定義 @Data static class RequestModel { private Integer id; private String name; } // プロパティが異なったクラス @Data static class Request2Model { private Integer no; private String title; }
マッピング処理の定義
マッピング処理はインターフェースに記述します。
@Mapper interface RequestMapper { // Interfaceに定数を定義する RequestMapper INSTANCE = Mappers.getMapper(RequestMapper.class); // プロパティ名が同名の場合のメソッド定義 RequestModel toRequestModel(InputModel inputModel); // プロパティ名が異なった場合のメソッド定義 @Mapping(source = "name", target = "title") @Mapping(source = "id", target = "no") Request2Model toRequest2Model(InputModel inputModel); }
上記のようにインターフェースにアノテーションで定義を書いていきます。プロパティ名が同名である場合は、アノテーションは不要です。プロパティ名が異なった場合は、その数のアノテーション定義を書くことになります。
RequestMapperインタフェース内にオブジェクトの変換処理がまとめられるので、とても見通しがよくなります。また、ModelMapperよりはるかに高速です。(計測している記事) 毎回インターフェースを定義する必要があるので、ModelMapperよりは少々手間がかかりますが、大量データを処理する場合は、速度的に十分リターンがあると思いますので使ってみてください。
メディア開発では、中途採用をはじめ長期インターンの募集もしております。興味があればぜひお声がけください。