[jdbcTemplate查询带有多个参数的准备好的语句

问题描述 投票:1回答:2

我正在像这样构建我的sql字符串:

    String sql = "SELECT * FROM horse WHERE 1=1 ";
    if (horse.getName() != null) {
        sql += "AND UPPER(name) LIKE ? ";
    }
    if (horse.getDescription() != null) {
        sql += "AND UPPER(description) LIKE ? ";
    }
    if (horse.getRating() != null) {
        sql += "AND rating=? ";
    }

我想根据传递的参数来查找实体的匹配项。因此,如果仅传递namerating,我将得到类似:SELECT * FROM horse WHERE 1=1 AND UPPER(name) LIKE ? AND rating=?

现在我通过sql字符串进行查询,如下所示:

List<Horse> matchingHorses = jdbcTemplate.query(sql, new Object[]{horse.getName()}, mapHorse());

这将返回正确的结果,但是我只能将我知道用户将要通过的参数传递给new Object[] {},否则我什么也不会得到。例如,如果用户传递这样的内容:

{
  "description":"desc"
}

即使存在带有“ desc”的description,我也不会得到任何结果。如果我这样做:

        List<Horse> matchingHorses = jdbcTemplate.query(sql, new Object[]{horse.getName(), horse.getDescription(), horse.getRating()}, mapHorse());

并且仅传递我得到的名字:

org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [SELECT * FROM horse WHERE 1=1 AND UPPER(name) LIKE ? ];
Invalid value "2" for parameter "parameterIndex" [90008-200]; nested exception is org.h2.jdbc.JdbcSQLDataException: Invalid value "2" for parameter "parameterIndex" [90008-200]

这是我的mapHorse()行映射器:

private RowMapper<Horse> mapHorse() {
        return (resultSet, i) -> {
            Long horseId = resultSet.getLong("id");
            String horseName = resultSet.getString("name");
            String horseDesc = resultSet.getString("description");
            int horseRating = resultSet.getInt("rating");
            return new Horse(
                horseId,
                horseName,
                horseDesc,
                horseRating,
            );
        };
}

我该如何正确实现?

java spring-boot jdbc prepared-statement jdbctemplate
2个回答
0
投票

您可以使用NamedParameterJdbcTemplate。

MapSqlParameterSource params = new MapSqlParameterSource();
if (horse.getName() != null) {
    sql += "AND UPPER(name) LIKE :name ";
    params.addValue("name", horse.getName());
}
if (horse.getDescription() != null) {
    sql += "AND UPPER(description) LIKE :description ";
    params.addValue("description", horse.getDescription());
}
if (horse.getRating() != null) {
    sql += "AND rating=:rating ";
    params.addValue("rating ", horse.getRating());
}
namedParameterJdbcTemplate.query(sql, params, mapHorse());

建议-如果您使用字符串生成器,则更好。


0
投票

您可以像使用String.formatNamedParameterJdbcTemplate一样>>

NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate("Your_Data_Source");
StringBuilder query = new StringBuilder();
query.append("SELECT * FROM horse WHERE 1=1");
if (horse.getName() != null) {
   query.append(String.format(" AND UPPER(name) LIKE '%%%s%%' ", horse.getName()))
}
if (horse.getDescription() != null) {
   query.append(String.format(" AND UPPER(description) LIKE '%%%s%%' ", horse.getDescription()));
}
if (horse.getRating() != null) {
   query.append(String.format("AND rating=%d",horse.getRating()));
}
return jdbcTemplate.query(query.toString(), Your_Row_Mapper);
© www.soinside.com 2019 - 2024. All rights reserved.