SpringJDBCTemplateを使用しています。
クエリ関数に渡す必要のあるパラメーターが条件付き/オプションであるシナリオがあります。たとえば、次のコードがあります。
List<RealTimeDTO> result = jdbcTemplate.query(sql, new Object[] {custId,
number, requestType, startDate, endDate}, new CCCRowMapper());
コードでは、custId, number, requestType, etc.
を渡しましたが、requestType
はオプションのパラメーターでありnull
またはempty
として返される可能性があるため、 null
またはempty
の場合は、Object[]
に渡されます。
この種の状況に対処するにはどうすればよいですか?
必要なパラメーターのみをObject[]
に渡すロジックを導入することはできますが、車輪の再発明ではなく、これを処理する組み込みの機能がすでにあるのではないかと考えていました。
1つのオプションは NamedParameterJdbcTemplate
を使用することです。したがって、パラメーター "list"(現在はMap
)を変更する必要はなく、SQLのみを変更します。
List<RealTimeDTO> query(String name) {
NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
String sql = "SELECT foo, bar" +
" FROM FooBar" +
" WHERE name" + (name == null ? " IS NULL" : "= :name");
Map<String, Object> params = new HashMap<>();
params.put("name", name);
return jdbcTemplate.query(sql, params, new CCCRowMapper());
}
[〜#〜]更新[〜#〜]
スキップする必要のある条件が多数あり、すべての条件が削除される可能性がある場合は、StringJoiner
を使用してWHERE
句を作成します。
List<RealTimeDTO> query(String name, String phone, int age) {
NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
StringJoiner where = new StringJoiner(" AND ", " WHERE ", "").setEmptyValue("");
if (name != null)
where.add("name = :name");
if (phone != null)
where.add("phone = :phone");
if (age != 0)
where.add("age = :age");
String sql = "SELECT foo, bar" +
" FROM FooBar" +
where;
Map<String, Object> params = new HashMap<>();
params.put("name", name);
params.put("phone", phone);
params.put("age", age);
return jdbcTemplate.query(sql, params, new CCCRowMapper());
}
? IS NULL OR name = ?
のような条件をチェックすることにより、静的SQLを使用できます。ただし、引数を2回渡し、引数の型(at.sql.Types
)を2回渡す必要があります。
String sql = "SELECT foo, bar" +
" FROM FooBar" +
" WHERE (? IS NULL OR name = ?) ";
jdbcTemplate.query(sql, new Object[]{name, name}, new int[]{Types.VARCHAR, Types.VARCHAR}, new CCCRowMapper());
IMOは、条件を使用するよりも実際には優れていません。