J'ai une table MySQL avec Foos. Chaque Foo a un code numérique non unique et un nom. Maintenant, je dois trouver si un Foo avec l'un de certains codes a un nom qui commence par une chaîne donnée. En SQL normal, ce serait trivial:
select * from FOO where CODE in (2,3,5) and NAME like 'bar%';
Mais comment pourrais-je faire cela correctement au printemps maintenant? Sans avoir besoin de l'opérateur `` comme '', je le ferais comme ceci:
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);
}
Cependant, avec "comme", rien ne semble fonctionner: NAME like :name%
, NAME like ':name%'
, ou NAME like ?%
lors de l'utilisation des espaces réservés au lieu des paramètres nommés.
Je pourrais être brutal et y entrer comme
String sql = "select * from FOO where CODE in (:codes) and NAME like '"+namePart+"%'";`
mais évidemment ce serait plus que bien si Spring désinfectait correctement les paramètres d'entrée etc, vous savez ...
Vous penseriez que Spring soutiendrait cela d'une manière ou d'une autre, mais je ne peux pas le comprendre.
Attendez, bien sûr, je devais "essayer une dernière chose de plus" avant de l'appeler un jour, et voilà, tous mes tests unitaires réussissent soudainement:
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);
}
Je n'ai pas pensé à entrer le "%" dans le paramètre, j'étais certain que Spring y échapperait automatiquement. Je me demande si je le fais bien?
Pour que les paramètres nommés fonctionnent, vous devez utiliser NamedParameterJdbcTemplate
params.put ("nom", "Joe%");
jdbcTemplate.query ("sélectionnez * dans FOO où CODE dans (: codes) et NAME comme: nom"
Sous une autre forme, j'ai rencontré le même problème, et j'ai essayé de le résoudre de cette manière:
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")));
}