UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【Java】ざっくりMapStruct

JavaのライブラリのMapStructを使うことになったので、ざっくり調べる

mapstruct.org

MapStruct は Annotation Processor を使って、Javaのオブジェクト間のマッピングに対するコードをコンパイル時に自動生成するマッピングライブラリ

複数のレイヤーで構成される大規模なJavaアプリケーションを作成するとき、ドメインモデルやDTOなどの複数のモデルを使用する必要がある

このように異なる複数のモデルを使用するに場合、Bean間のマッピングが大変

MapStructはこれを簡単にしてくれる便利なライブラリ

MapStructを使用すると、インターフェイスを作成するだけで済む

2つのクラスを用意する

public class FreshFruit {
    private String name;
    private String description;
    // getters and setters
}
 
public class Fruit {
    private String name;
    private String description;
    // getters and setters
}

インターフェースを用意する

@Mapper
public interface FruitTranslator {
    Fruit translate(FreshFruit freshFruit);
    FreshFruit translate(Fruit fruit);
}

mvn clean installで、MapStruct処理をトリガーできる

これにより自動で実装クラスが生成される

public class FruitTranslatorImpl
  implements FruitTranslator {
    @Override
    public Fruit translate(FreshFruit freshFruit) {
        if ( freshFruit == null ) {
            return null;
        }
        Fruit fruit = new Fruit();
        banana.setName( freshFruit.getName() );
        banana.setDescription( freshFruit.getDescription() );
        return fruit;
    }
    @Override
    public FreshFruit translate(Banana fruit){
        if ( fruit == null ) {
            return null;
        }
        FreshFruit freshFruit = new FreshFruit();
        freshFruit.setName( fruit.getName() );
        freshFruit.setDescription( fruit.getDescription() );
        return freshFruit;
    }
}

もしフィールド名が違う場合は@Mappingを使用し、target属性にマッピングされるフィールド名、source属性にマッピングするフィールド名を指定する

@Mapper
public interface FruitTranslator {
    @Mapping(target="name", source="fruitsName")
    Fruit translate(FreshFruit freshFruit);

    @Mapping(target="fruitsName", source="name")
    FreshFruit translate(Fruit fruit);
}

@Mappingには他にも、定数のマッピングや、数値や日付のフォーマットなどができる

他参考

https://qiita.com/kentama/items/7c2693c0b4311c64ea27