MyBatisには、org.apache.ibatis.type.ArrayTypeHandler
があって、java.sql.Arrayとのマッピングを行ってくれますが、パラメータ設定時と、結果取得時でマッピングが異なるので注意が必要です。
実際のコードを見たほうがわかりやすいので、現時点のコードを引用します。
public class ArrayTypeHandler extends BaseTypeHandler<Object> { public ArrayTypeHandler() { super(); } @Override public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException { ps.setArray(i, (Array) parameter); } @Override public Object getNullableResult(ResultSet rs, String columnName) throws SQLException { Array array = rs.getArray(columnName); return array == null ? null : array.getArray(); } @Override public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException { Array array = rs.getArray(columnIndex); return array == null ? null : array.getArray(); } @Override public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { Array array = cs.getArray(columnIndex); return array == null ? null : array.getArray(); } }
パラメータ設定時(setNonNullParameter
メソッド)では、java.sql.Array
を パラメータとして求めますが、結果取得時(getNullableResult
メソッド)だと、java.sql.Array
からgetArray
したもの(たとえばPostgreSQLのintの配列(int[]
)だと、Javaのint[]
)が返却されます。
そのため、同じEntityを使ってInsertとSelectを行うということができません。
java.sql.Arrayを生成する際に、配列のタイプを文字列で指定する必要があり、汎用的なTypeHandlerを作るのが難しいのでこのようになってしまっているのではと思いますが、そのあたりの理由を知っていないと、嵌りそうですね。
同じEntityを使いたい場合には、ArrayTypeHandler
を使わずに、そのARRAYの型に応じたTypeHandlerを独自に作ることになりそうです。TypeHandler自体はとてもシンプルなので、実装も簡単です。
参考までに、List<Integer>
と、PostgreSQLのint[]
をマッピングするTypeHandlerの実装を以前作ったので、リンクしておきます。