テーブル列の定義では、数値項目でもNULLも許容することができます。JDBCで値を取得するときは、通常は
PreparedStatement conn.prepareStatement(...);
ResultSet rset = stmt.executeQuery();
while (rset.next() {
Integer value = rset.getInt(1);
}
のようにしますが、getInt()やgetLong()などは「項目値がSQL nullの場合には0を返す」という仕様となっているため、正しい値を取得することができません。あらかじめ項目値がnullかどうかをチェックできれば良いのですが、APIとして用意されているのはwasNull()という、一旦値を取り出した後にnullだったかどうかを判定するものです。これを素直に使うと
Integer value = rset.getInt(1);
if (rset.wasNull()) {
value = null;
}
という形になります。ただ、項目数が多いとこの記述を1つ1つ書いていくのは大変ですし、コードの見通しが悪くなります。その処理を関数化すればもうちょっとすっきりするので、良い関数を考えてみます。
private Integer fixInt(ResultSet rset, int columnIndex) {
Integer result = rset.getInt(columnIndex);
if (rset.wasNull()) {
result = null;
}
return result;
}
:
Integer value = fixInt(rset, 1);
ただ、メモリリークの温床となりやすいResultSetをむやみに引数として他に渡すのは避けたいところです。そこで、
private Integer fixInt(int value, boolean isNull) {
return isNull ? null : value;
}
:
Integer value = fixInt(rset.getInt(1), rset.wasNull());
などでいかがでしょうか。こういう書き方はテンプレされていても良かろうと思うのですが、あまりに些細なので埋もれてしまうのでしょうかね。