タイガー!タイガー!じれったいぞー!(SE編)

AS400, Java, JavaEE, JSF等の開発、習慣など。日々の気づきをまとめたブログ(備忘録)

【Mybatis】DBのCHARの値をtrim化して取得する(resultMapの場合)

またもMybatisネタです。

前回、DBのCHARの値をtrim化して取得する方法を書いたのですが、SELECT句の結果タイプがresultTypeだったため、TypeHandlerを使って trim処理をラップする方法が使えました。

tigertaizo.hatenablog.com

しかし今回は、SELECT句の結果タイプがresultMapの場合です。

次のような事例になります。

<resultMap id="salesModelMap" type="SalesModel">
    <id property="salesId" column="FIELD_KEY"/>
    <result property="salesDate" column="FIELD_NAME1"/>
    <result property="sectionCode" column="FIELD_NAME2"/>
    <result property="remarks" column="FIELD_NAME3"/>
    <!-- 省略 -->
</resultMap>

<select id="fetchSalesByPk" resultType="salesModelMap">
    select *
    from SALES
    where FIELD_KEY= #{id}
</select>

ズバリ、mybatisのグローバルConfigに書いたtypeHandlerが機能してくれませんでした。。。残念!

mybatis-config.xml

<typeHandlers>
    <typeHandler handler="jp.co.companyName.commons.daos.myTypeHandler.StringTrimmingTypeHandler"/>
</typeHandlers>

resultMapは、RDBのテーブルのカラム名JavaのModelのプロパティ名をつないでくれるため、同一のテーブルを複数の条件でSELECTされる場合には、<select></select>の中身がすっきりします。「select *」で統一できるようになるので。

これがなかなか苦戦しました。結局、うまい方法が見つけられず・・・。

解決方法

結果的に、私が出した方法はこちら。

  • GlobalのtypeHandlersはそのまま残す(resultTypeでは機能するため)。
  • 個別SQLのresultMapの各項目ごとにtypeHandlerを定義する(超・手間です!)。
  • 合わせて、typeHandler用Classのエイリアスをglobalで定義する(極力短い名前とする→コード量を抑制する目的)。

mybatis-config.xml

<typeAliases>
    <typeAlias alias="StringTrim" type="jp.co.companyName.commons.daos.myTypeHandler.StringTrimmingTypeHandler"/>
    <typeAlias alias="SalesJournalModel" type="jp.co.companyName.appName.models.SalesModel"/>
</typeAliases>
<typeHandlers>
    <typeHandler handler="jp.co.companyName.commons.daos.myTypeHandler.StringTrimmingTypeHandler"/>
</typeHandlers>

<mappers>
    <mapper resource="sqls/Sales.xml"/>
</mappers>

Sales.xml

<resultMap id="salesModelMap" type="SalesModel">
    <id property="salesId" column="FIELD_KEY"/>
    <result property="salesDate" column="FIELD_NAME1"/>
    <result property="sectionCode" column="FIELD_NAME2" typeHandler="StringTrim"/>
    <result property="remarks" column="FIELD_NAME3" typeHandler="StringTrim"/>
    <!-- 省略 -->
</resultMap>

<select id="fetchSalesByPk" resultType="salesModelMap">
    select *
    from SALES
    where FIELD_KEY= #{id}
</select>

resultMapのresultタグのCHARフィールドだけに対して、「typeHandler="StringTrim"」を入れていきます。

フィールドの数は多い場合、ひたすらカット&ペーストを行ってください(TT)。

この方法が最適解かどうかは、微妙なところではありますが、とりあえずこの方法でやりたいことは実現できているので良しとしましょう。