22

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はどういうわけかこれをサポートすると思うかもしれませんが、私には理解できません。

4

4 に答える 4

37

もちろん、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が自動的にエスケープすることを確信していました。私はそれを正しくやっているのだろうか?

于 2012-06-19T15:08:37.450 に答える
4

名前付きパラメーターを機能させるには、 NamedParameterJdbcTemplateを使用する必要があります

params.put("name", "Joe%");

jdbcTemplate.query("select * from FOO where CODE in (:codes) and NAME like :name" 
于 2012-06-19T15:09:04.467 に答える
4

別の形式では、同じ問題が発生し、次の方法で解決しようとしました。

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")));
}
于 2018-04-26T14:13:18.517 に答える
0

上記のコードに問題があります。コード構造は正しいですが、変数のマッピングに問題があります。「IndexOutofBound」SQL例外エラーとしてエラーメッセージが表示されます。

このエラーを回避するために、クラス「MySqlParameterSource」を使用して変数を適切にマップします。そのクラスのオブジェクトを作成し、変数を内部に渡して変数をマップする必要がありました。

例としてこれに従ってください。

 public List<Products> getParticular2(@RequestParam String charc){

        String sql ="select * from products where name like :name";

        Map<String, Object> params = new HashMap<String, Object>();
                params.put("name", charc+"%");
        
        MapSqlParameterSource param = new MapSqlParameterSource(params);
        
        List <Products> list = template.query(sql, param, new 
                                BeanPropertyRowMapper<>(Products.class));
        return list;
    }
于 2022-01-03T05:45:28.633 に答える