LoginSignup
6
4

More than 5 years have passed since last update.

MapStructでBeanマッピング その3

Posted at

前回の続き

http://qiita.com/kentama/items/09a8573bd5d0831b470e
http://qiita.com/kentama/items/55c71ca28f0c5af8d4ed

型変換とフォーマット

int -> String のようにマッピング時に型変換を行うことができる。
その際に、フォーマットの指定を行うこともできる。

Bean
public class Hoge {
    private String date;
    private String number;

   // constructor/getter/setter
}

public class Fuga {
    private LocalDate date;
    private int number;

   // constructor/getter/setter
}

Mapperの作成

@Mapper
public interface ConversionMapper {
    ConversionMapper INSTANCE = Mappers.getMapper(ConversionMapper.class);

    @Mapping(target = "date", source = "date", dateFormat = "yyyy年MM月dd日") // (1)
    @Mapping(target = "number", source = "number", numberFormat = "#,###") // (2)
    Hoge convert(Fuga fuga);
}

(1) dateFormat 属性に日付のフォーマットを指定する。
(2) numberFormat 属性に数値のフォーマットを指定する。

実行

Fuga fuga = new Fuga(LocalDate.of(2017, 4, 1), 1234567890);
Hoge hoge = ConversionMapper.INSTANCE.convert(fuga);

System.out.println(hoge.getDate()); // 2017年04月01日
System.out.println(hoge.getNumber()); // 1,234,567,890

リストの型変換

@IterableMapping を使用することで、リストの型変換もすることができる。
今回は、int -> Stringの変換を行い、3桁のゼロ埋めをする。

Mapperの作成

@Mapper
public interface ConversionMapper {
    ConversionMapper INSTANCE = Mappers.getMapper(ConversionMapper.class);

    @IterableMapping(numberFormat = "000")
    List<String> zeroPadding(List<Integer> numbers);
}

実行

List<String> numbers = ConversionMapper.INSTANCE.zeroPadding(Arrays.asList(1, 2, 56, 76, 863));
System.out.println(numbers); // [001, 002, 056, 076, 863]

Mapperの再利用

Mapperから他のMapperを利用することができる。
MapStructが生成したMapper、または独自に実装したMapperを指定できる。

Bean
public class Hoge {
    private String date;

    // constructor/getter/setter
}

public class Fuga {
    private LocalDate date;

    // constructor/getter/setter
}

Mapperの作成

今回は LocalDate -> String変換 の独自Mapperを作成し、それを再利用させる。

独自Mapper
public class LocalDateMapper {
    public String asString(LocalDate date) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        return date != null ? date.format(formatter) : null;
    }
}
@Mapper(uses = LocalDateMapper.class) // (1)
public interface InvokingOtherMapper {
    InvokingOtherMapper INSTANCE = Mappers.getMapper(InvokingOtherMapper.class);

    Hoge fugaToHoge(Fuga fuga);
}

(1) uses 属性に再利用するMapperを指定する。

実行

Fuga fuga = new Fuga(LocalDate.of(2017, 4, 1));
Hoge hoge = InvokingOtherMapper.INSTANCE.fugaToHoge(fuga);

System.out.println(hoge.getDate()); // 2017年04月01日

限定子(Qualifier)の利用

独自に作成したマッピングロジックにアノテーションを付与し、Mapperで独自のマッピングロジックを利用するようにすることができる。
ここでは例として大文字と小文字に変換するマッピングを行う。

Bean
public class Hoge {
    private String hoge1;
    private String hoge2;

    // constructor/getter/setter
}

public class Fuga {
    public String fuga1;
    public String fuga2;

    // constructor/getter/setter
}

マッピングロジックの作成

public class Characters {

    public String upperCase(String string) {
        return (string == null) ? null : string.toUpperCase();
    }

    public String lowerCase(String string) {
        return (string == null) ? null : string.toLowerCase();
    }
}

アノテーションの作成

@Qualifier
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface CharacterConverter {
}

@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface ToUpper {
}

@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface ToLower {
}

アノテーションの付与

マッピングロジックに作成したアノテーションを付与する。

@CharacterConverter
public class Characters {

    @ToUpper
    public String upperCase(String string) {
        return (string == null) ? null : string.toUpperCase();
    }

    @ToLower
    public String lowerCase(String string) {
        return (string == null) ? null : string.toLowerCase();
    }
}

Mapperの作成

@Mapper(uses = Characters.class) // (1)
public interface HogeFugaMapper {
    HogeFugaMapper INSTANCE = Mappers.getMapper(HogeFugaMapper.class);

    @Mapping(target = "hoge1", source = "fuga1", qualifiedBy = { CharacterConverter.class, ToUpper.class }) // (2)
    @Mapping(target = "hoge2", source = "fuga2", qualifiedBy = { CharacterConverter.class, ToLower.class }) // (3)
    Hoge fugaToHoge(Fuga fuga);
}

(1) マッピングロジッククラスを指定する
(2)(3) qualifiedBy 属性にマッピングロジッククラスのクラスレベルと、メソッドレベルに指定したアノテーションを指定する。

実行

Fuga fuga = new Fuga("abc", "XYZ");
Hoge hoge = HogeFugaMapper.INSTANCE.fugaToHoge(fuga);

System.out.println(hoge.getHoge1()); // ABC
System.out.println(hoge.getHoge2()); // xyz

続きは次回。

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4