Orikaとは
POJOやBeanにマッピング処理できるライブラリ。
マッピングの指定や型変換が楽に行えて便利。
オブジェクトのプロパティを自動Mappingする
使用環境
ビルドツール | フレームワーク |
---|---|
Gradle | Spring Boot |
フレームワークはOrikaのオブジェクトをDIするために使用してます。(後述)
①ライブラリの使用準備
build.gradleのdependenciesに以下の1行を追加。
versionについては適宜読み替えてください
compile group: 'ma.glasnost.orika', name: 'orika-core', version: '1.5.4'
② MapperFactoryをインスタンス化する
使用するクラスでnewしてもいいが、公式にはシングルトンにした方が
パフォーマンスいいみたいなので今回はSpringのDI機能を使用してシングルトン化しました。
※シングルトンってなんぞやって人はここでも見てくだせぇ
@Componet
public class ConvertMapper {
@Bean
public MapperFactory getMapperFactory(){
MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
return mapperFactory;
}
}
@Autowired
private MapperFactory mapperFactory;
##③ Convertの元クラスと先クラスを設定する
Convert元クラス名に変換元となるオブジェクト(データが設定されている方)のクラス名を設定、
Convert先クラス名に変換先となるオブジェクト(これから設定したい方)のクラス名を設定します。
BoundMapperFacade<Convert元クラス名, Convert先クラス名> boundMapperFacade =
mapperFactory.getMapperFacade(Convert元クラス名.class, Convert先クラス名.class);
##④ Convertの実施
Convert先のオブジェクト = boundMapperFacade.map(Convert元のオブジェクト);
これにてConvert完了です。
オブジェクトのプロパティを手動Mappingする方法
以下のような構造のクラスがありAからBに変換したい場合では、
フィールド変数名が異なるため自動マッピングでは変換できません。
型 | Convert元 | Convert先 |
---|---|---|
ClassA | ClassB | |
int | id | id |
String | propatyA | propatyB |
そのため、オブジェクトの変換を行う前に明示的に対となるプロパティ名を指定してあげる必要があります。
※オブジェクトのプロパティを自動Mappingするの手順③までは同じ
mapperFactory.classMap(InputEstimateData.class, EstimateDataValue.class)
.field("propatyA","propatyB") // マッピング対象となるプロパティ名を指定する。
.byDefault() // 残りは自動Mappingする
.register();
// Convertの実行も同じ
Convert先のオブジェクト = boundMapperFacade.map(Convert元のオブジェクト);
Convertで型やデータの変換を行う
Convertにて特定の型を変換したい場合には以下のことを行う。
##①型変換用のクラスを作成する
変換条件に応じて下記のクラスを継承したクラスを作成する。
単方向のみの変換 | 双方向の変換 |
---|---|
ma.glasnost.orika.CustomConverter | ma.glasnost.orika.converter.BidirectionalConverter |
例は、java.sql.Timestamp型とjava.util.LocalDateTime型の双方向変換のクラス
import java.sql.Timestamp;
import java.time.LocalDateTime;
public class DataConverter extends BidirectionalConverter<LocalDateTime, Timestamp> {
@Override
public Timestamp convertTo(LocalDateTime source, Type<Timestamp> destinationType, MappingContext mappingContext) {
return Timestamp.valueOf(source);
}
@Override
public LocalDateTime convertFrom(Timestamp source, Type<LocalDateTime> destinationType, MappingContext mappingContext) {
return source.toLocalDateTime();
}
}
##② ConverterFactoryに変換用のクラスを登録する
登録方法には2通りある。
方法1. すべての変換に対して適用する場合
ConverterFactory converterFactory = mapperFactory.getConverterFactory();
converterFactory.registerConverter(new DataConverter());
方法2. 変換時に対象のプロパティを指定する場合
ConverterFactory converterFactory = mapperFactory.getConverterFactory();
converterFactory.registerConverter("管理名",new DataConverter());
上記の内容をMapperFactoryのインスタンスを生成しているメソッドで設定する。
@Componet
public class ConvertMapper {
@Bean
public MapperFactory getMapperFactory(){
MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
// ConverterFactoryの取得
ConverterFactory converterFactory = mapperFactory.getConverterFactory();
// 変換時に対象のプロパティを指定する場合
converterFactory.registerConverter("管理名",new DataConverter());
// すべての変換に対して適用する場合
converterFactory.registerConverter(new DataConverter());
return mapperFactory;
}
}
##③ 変換の設定とConvertの実施
BoundMapperFacade<Convert元クラス名, Convert先クラス名> boundMapperFacade =
mapperFactory.getMapperFacade(Convert元クラス名.class, Convert先クラス名.class);
// 方法2の場合には変換条件を設定する(方法2の場合は不要)
// java.util.LocalDateTimeをjava.sql.Timestamp型に変換してマッピングする
mapperFactory.classMap(Convert元クラス名.class, Convert先クラス名.class)
.fieldMap("Convert元クラスのマッピングさせたいプロパティ名","Convert先クラスのマッピングさせたいプロパティ名")
.converter("ConverterFactoryに登録した時に指定した管理名")
.add()
.byDefault()
.register();
// Convertの実行も同じ
Convert先のオブジェクト = boundMapperFacade.map(Convert元のオブジェクト);
#あとがき
わりかし便利だけどあまり表に出てこないBeanMapperのOrikaの使い方でした。
ここに書いてる内容でだいたいのことはできる感じです。
日の目を浴びないのはLombokですべてのプロパティに引数を設定するコンストラクタを作れって話ですが・・・
結局、それではGetter地獄からは抜け出せません。
Orikaはプロパティ名さえ同じであれば自動的にマッピングしてくれるのでこれはこれで便利ですね。