我正在像这样构建我的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=? ";
}
我想根据传递的参数来查找实体的匹配项。因此,如果仅传递name
和rating
,我将得到类似: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,
);
};
}
我该如何正确实现?
您可以使用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());
建议-如果您使用字符串生成器,则更好。
您可以像使用String.format
和NamedParameterJdbcTemplate
一样>>
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);