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

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

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

先週に続いて、Mybatisネタです。

3年半前に自分が書いた記事では、何ともおダサい方法で、トリム化を行っていました。

「(4) CHARフィールドのトリムがされない」の部分です。

tigertaizo.hatenablog.com

当時、Mybatisの勉強を始めたばかりだったとはいえ、SQL文でRTRIM関数を行っていました。
これでは、SQLパフォーマンスが悪くなってしまいます。。。

TypeHandlerを使って trim処理をラップする

mybatis.org

公式サイトによりますと、次のように書いてありました。

MyBatis が PreparedStatement のパラメーターをセットするとき、
あるいは ResultSet から値を取得するときには、
必ずその Java タイプに対応する TypeHandler が使用されます。

このTypeHandlerと呼ばれる型変換機能を独自に実装してあげることで、Modelに格納する際にtrimやenum変換などの独自処理を追加できるようです。

まずは TypeHandlerクラスの作成です。

StringTrimmingTypeHandler.java

package jp.co.companyName.commons.daos.myTypeHandler;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;

@MappedJdbcTypes(JdbcType.CHAR)
public class StringTrimmingTypeHandler extends BaseTypeHandler<String> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
            throws SQLException {
        ps.setString(i, trim(parameter));
    }

    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return trim(rs.getString(columnName));
    }

    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return trim(rs.getString(columnIndex));
    }

    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return trim(cs.getString(columnIndex));
    }

    private String trim(String s) {
        if (Objects.isNull(s)) {
            return "";
        } else {
            return s.trim();
        }
    }
}

mybatis-config.xml

  • 次にmybatisの設定で、typeHandlersタグ内に独自に作成したtypeHandlerを設定します。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <typeHandlers>
        <typeHandler handler="jp.co.companyName.commons.daos.myTypeHandler.StringTrimmingTypeHandler"/>
    </typeHandlers>
    <environments default="MAIN">
        <environment id="MAIN">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="sqls/Sales.xml"/>
    </mappers>
</configuration>

これにより、次のような実際のSQL-SELECT文で、戻り値がresultTypeでMODELを定義した場合に、MODEL内の文字列項目がきちんとtrim化されて格納されていました!! オッケー、オッケー!!

<select id="fetchSalesModel" resultType="SalesModel">
    select 
        FIELD_NAME1 as salesDate,
        FIELD_NAME2 as sectionCode,
        <!-- 省略 -->
    from TABLE_NAME 
    where FIELD_NAME3 = #{paramValue1}
</select>

それにしても、Mybatisの公式サイトは非常にわかりやすく書かれていて、大変助かります。

感謝ですね!