int[] → ArrayTypeHandler

SQLクエリの結果から、int [ ]で受け取るための mybatis  ArrayTypeHandler

先日、PostgreSQL 再帰クエリの結果から、INTEGER型 配列を Integer[] で取得するものを
書きました。
oboe2uran.hatenablog.com

Integer [ ] ではなくて、やはり、int [ ] で取得したい場合のタイプハンドラは、以下のように用意します。

import java.sql.Array;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
/**
 * int[] → ArrayTypeHandler
 */
public class IntArrayTypeHandler extends BaseTypeHandler<int[]>{
   @Override
   public void setNonNullParameter(PreparedStatement ps, int i, int[] parameter, JdbcType jdbcType) throws SQLException{
      Connection conn = ps.getConnection();
      Object[] po = new Object[parameter.length];
      int x = 0;
      for(int p:parameter){
         po[x] = Integer.valueOf(p);
         x++;
      }
      Array array = conn.createArrayOf("integer", po);
      ps.setArray(i, array);
   }

   @Override
   public int[] getNullableResult(ResultSet rs, String columnName) throws SQLException{
      return getArray(rs.getArray(columnName));
   }

   @Override
   public int[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException{
      return getArray(rs.getArray(columnIndex));
   }

   @Override
   public int[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException{
      return getArray(cs.getArray(columnIndex));
   }

   private int[] getArray(Array array){
      if (array==null){
         return null;
      }
      try{
         Object[] ary = (Object[])array.getArray();
         int[] rtn = new int[ary.length];
         int i = 0;
         for(Object o:ary){
            rtn[i] = Integer.valueOf(o==null ? "0" : o.toString());
            i++;
         }
         return rtn;
      }catch(Exception e){
      }
      return null;
   }
}

mybatis は、resultMap のタイプハンドラ定義したハンドラの getNullableResult(ResultSet rs, String columnName) を
呼び出すので、
この返却値が、int[] になるように BaseTypeHandler の継承を用意すればいいのです。

このハンドラをSQLMap で記述する resultMap の result typeHandler 属性で指定します。

<result column="aryid"   property="aryid"
     typeHandler="sample.IntArrayTypeHandler"
     jdbcType="INTEGER"  javaType="int" />

jdbcType="ARRAY" と書くべきなのかもしれませんが、INTEGER でも、NUMERIC でも
実際は動作します。
jdbcType、javaType、両方ともに省略しても動作します。