私はFoosでMySQLテーブルを持っています。各Fooには、一意ではない数値コードと名前があります。ここで、特定のコードの1つを持つFooが、指定された文字列で始まる名前を持っているかどうかを調べる必要があります。通常のSQLでは、これは簡単です。
select * from FOO where CODE in (2,3,5) and NAME like 'bar%';
しかし、今春にこれを適切に行うにはどうすればよいですか? 「like」演算子を必要としない場合は、次のようにします。
public List<Foo> getByName(List<Integer> codes, String namePart) {
String sql = "select * from FOO where CODE in (:codes) and NAME=:name"
Map<String,Object> params = new HashMap<String,Object>();
params.put("codes", codes);
params.put("name", namePart);
return getSimpleJdbcTemplate().query(sql, new FooRowMapper(), params);
}
ただし、「like」では何も機能しないようです:NAME like :name%
、NAME like ':name%'
、またはNAME like ?%
名前付きパラメーターの代わりにプレースホルダーを使用する場合。
私は残忍で、次のように入力することができます
String sql = "select * from FOO where CODE in (:codes) and NAME like '"+namePart+"%'";`
ただし、Springが入力パラメーターを適切にサニタイズする場合など、明らかにそれはいいことではありません。
Springはこれを何らかの形でサポートすると思いますが、私にはわかりません。
待ってください、もちろん、私はそれを1日と呼ぶ前に「もう1つ最後のことを試してみる」必要がありました、そして驚いたことに、すべてのユニットテストが突然パスしました。
public List<Foo> getByName(List<Integer> codes, String namePart) {
String sql = "select * from FOO where CODE in (:codes) and NAME like :name"
Map<String,Object> params = new HashMap<String,Object>();
params.put("codes", codes);
params.put("name", namePart+"%");
return getSimpleJdbcTemplate().query(sql, new FooRowMapper(), params);
}
パラメータに「%」を入力することは考えていませんでした。Springが自動的にエスケープするのは確かでした。ちゃんとやってるのかな?
名前付きパラメーターを機能させるには、 NamedParameterJdbcTemplate を使用する必要があります
params.put( "name"、 "Joe%");
jdbcTemplate.query( "select * from FOO where CODE in(:codes)and NAME like:name"
別の形で、私は同じ問題に遭遇し、この方法で解決しようとしました:
public List<MyEntity> getMyEntityValuesBySearchText(String searchText) {
String query = "SELECT * FROM MY_ENTITY_TABLE WHERE NAME LIKE ?";
return this.getJdbcTemplate().query(query, new String[] { "%" + searchText + "%" },
(rs, rowNum) -> new MyEntity(rs.getLong("PK"), rs.getString("NAME")));
}