10

これは JDBCTemplates の初めての経験であり、次のようなクエリを使用する必要がある場合に遭遇しました。

SELECT * FROM table WHERE field IN (?)

それ、どうやったら出来るの?リスト/配列の値を渡そうとしましたが、うまくいかず、例外が発生しました。私の現在のコードは次のようになります。

Long id = getJdbcTemplate().queryForLong(query, new Object[]{fieldIds});

Spring Documentationは、必要な数の「?」を生成する以外にこれを行う方法はないと述べています。パラメーター リストのサイズに合わせてプレースホルダーを配置します。回避策はありますか?

4

5 に答える 5

52

SimpleJdbcDaoSupportの代わりにNamedParameterJdbcTemplateを使用する回避策があり、次のようなことができます。

List integerList = Arrays.asList(new Integer[] {1, 2, 3});
Map<String,Object> params = Collections.singletonMap("fields", integerList);    
Long id = namedParameterJdbcTemplate.queryForLong("SELECT * FROM table WHERE field IN (:fields)", params);

ただし、これには、使用している DB に応じて、リストで渡すことができるパラメーターの数に関して壊滅的な制限が生じる可能性があります。

于 2010-12-22T15:04:48.990 に答える
3

これを単一の「?」として実行できるとは思いません。Spring JDBC テンプレートとは関係ありません。コア SQL です。

必要な数だけ (?, ?, ?) を構築する必要があります。

于 2010-12-21T22:44:38.620 に答える
3

長いリスト (例: Oracle には 1000 項目の制限があります) の場合は、それをより多くの選択に分けることができます。

List<Long> listIds = Arrays.asList(1L, 2L, ..... , 10000L); // list with ids

String query = "select NOTE from NOTE where ID in (:listIds)";

List<String> noteListResult = new ArrayList<>();

int current = 0;
int iter = 100;

while (current < listIds.size()) {
    Map<String, List<Long>> noteIdsMap = Collections.singletonMap("listIds",
            listIds.subList(current, (current + iter > listIds.size()) ? listIds.size() : current + iter));

    List<String> noteListIter = namedParameterJdbcTemplate.queryForList(query, noteIdsMap, String.class);
    noteListResult.addAll(noteListIter);

    current += iter;
}

return noteListResult;
于 2016-02-25T14:43:58.750 に答える