LoginSignup
0
0

More than 3 years have passed since last update.

【KMapper】複数ソースからマッピングする【Kotlin】

Last updated at Posted at 2020-03-07

自作のKotlin Object to Kotlin Objectマッパー、KMapperの機能紹介です。

バージョンはKMapper 0.12で書いています。

複数ソースからマッピングする。

KMapperでは以下のように複数のPair/Map/オブジェクトからマッピングを行うことができます。

data class Dst(
    val fooId: Int,
    val barName: String,
    val bazDescription: String?
)

// ソースになるクラス、fooIdがフィールドに無い
data class Src(
    val barName: String,
    val bazDescription: String?
)

fun mapping(fooId: Int, src: Src) {
    val mapper = KMapper(::Dst)
    // Srcに足りないフィールドをPair<String, Int>で補い、srcからマッピング
    val dst: Dst = mapper.map("fooId" to fooId, src)
}

利用想定

「1対多のテーブルで、まず1を永続化してIDを生成し、そのIDを用いて多を永続化する」というような状況や、「複数のオブジェクトを合わせて1つのオブジェクトを作る」という状況での利用を想定しています。
既存のJava系ライブラリでは、このような場合に「1度マッパーでオブジェクトを生成し、それに対してセッター経由でセットする」ような書き方になりがち1ですが、KMapperではそのようなマッピング処理もまとめて書くことができます。

同名のフィールドが複数有る場合について

同名のフィールドが複数あった場合は、先に入力した方を優先して取り扱います。
従って、重要な値ほど初めに書く必要が有ります。

競合が解消できない場合

複数オブジェクト間で競合が発生した場合はKGetterIgnoreアノテーションを用いて以下のように書けます。
以下はSrc1Src2の2クラスにそれぞれKGetterIgnoreを設定することで、どちらの値を先に入れてマップしても同じ値が返るようにした例です。

data class Src1(val arg1: Int, val arg2: String, @get:KGetterIgnore val arg3: Short)
data class Src2(@get:KGetterIgnore val arg2: String, val arg3: Int, val arg4: String)

data class Dst(val arg1: Int, val arg2: String, val arg3: Int, val arg4: String)

fun test() {
    val src1 = Src1(1, "2-1", 31)
    val src2 = Src2("2-2", 32, "4")

    val mapper = KMapper(::Dst)

    val dst1 = mapper.map(src1, src2)
    val dst2 = mapper.map(src2, src1)

    assertEquals(dst1, dst2)
    assertEquals(Dst(1, "2-1", 32, "4"), dst1)
}

  1. あくまで自分が把握している範囲の話なので、そうじゃないライブラリも有るかもしれません。 

0
0
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
0
0