【Mybatis】TypeHandlerでValueObjectへ値をマッピングできるようにしてみる
タイトルの通り、TypeHandlerでValueObjectへマッピングできるようにしてみたので記事にしてみました。
Motivation
XMLにこんな感じでどのカラムをマッピングするか書いてたんですが、今後ValueObjectが増えるたびに定義しなきゃいけないのか...とツラミを感じていました。
↓こんな感じにすれば定義の共通化自体は可能なのですが、カラムの名前を都度気にしなきゃいけないのもバグりポイントなのでどうにかしたいなって思ってました。(調べればXMLの設定でもこの辺いい感じに解決できるのかもしれませんけど...)
<resultMap id="ValueObject" type="org.test.hoge.ValueObject">
<constructor>
<idArg javaType="java.lang.String" column="value" />
</constructor>
</resultMap>
<association property="value" resultMap="org.test.hoge.Dao.ValueObject" />
TypeHandlerでマッピングできるようにする
型がTypeHandlerでサポートされていれば、StringやIntなどのプリミティブな型同様何も気にせずselectできます。
リフレクション使ってるので嫌な人は見ない方がいいと思います。
あとkotlinで書いてます。(javaで書くとどうなるかも未検証... )
まずはValueObjectのabstractなclassを作ります。(equalsとhashCodeは適当)
abstract class ValueObject<E>(open val value: E) {
override fun equals(other: Any?): Boolean {
return value == other
}
override fun hashCode(): Int {
return value?.hashCode() ?: 0
}
}
あとはtypehandlerを定義します。ValueObjectを継承したクラスのコンストラクタにStringなvalue一つだけのコンストラクタを含む前提です。
@MappedTypes(
SubVO::class,
)
class StringValueObjectTypeHandler<E : ValueObject<String>>(val type: Class<E>) : BaseTypeHandler<E>() {
override fun setNonNullParameter(ps: PreparedStatement?, i: Int, parameter: E, jdbcType: JdbcType?) {
ps?.setString(i, parameter.value)
}
override fun getNullableResult(rs: ResultSet?, columnName: String?): E? {
return rs?.getString(columnName)?.let { valueObject(it) }
}
override fun getNullableResult(rs: ResultSet?, columnIndex: Int): E? {
return rs?.getString(columnIndex)?.let { valueObject(it) }
}
override fun getNullableResult(cs: CallableStatement?, columnIndex: Int): E? {
return cs?.getString(columnIndex)?.let { valueObject(it) }
}
private fun valueObject(value: String): E {
val c = type.kotlin.constructors.first {
it.parameters.size == 1 && it.parameters.first().type == typeOf<String>()
}
return c.call(value)
}
}
valueの型に応じてTypeHandlerを複数作るか、 it.parameters.first().type == typeOf<String>()
の比較でジェネリクスを使えばいける気もする(試してない)
Author And Source
この問題について(【Mybatis】TypeHandlerでValueObjectへ値をマッピングできるようにしてみる), 我々は、より多くの情報をここで見つけました https://qiita.com/morimorim/items/1d96cc3b76f0e13d122d著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .