22

我有一个带有 Foos 的 MySQL 表。每个 Foo 都有一个数字非唯一代码和一个名称。现在我需要查找是否有任何具有某些代码之一的 Foo 恰好具有以给定字符串开头的名称。在普通 SQL 中,这将是微不足道的:

select * from FOO where CODE in (2,3,5) and NAME like 'bar%';

但是我现在如何在春天正确地做到这一点?不需要“喜欢”运算符,我会这样做:

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

等等,当然我必须“再尝试最后一件事”才能结束一天,你瞧,我所有的单元测试突然通过了:

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

上面的代码有问题。代码结构正确,但映射变量有问题。您将收到错误消息“索引超出范围”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 回答