Reputation: 1159
I am building my sql
string like this:
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=? ";
}
I want to find a match for entity depending on which parameters are passed. So if only name
and rating
are passed I would get something like: SELECT * FROM horse WHERE 1=1 AND UPPER(name) LIKE ? AND rating=?
Now I pass the sql
string to query like this:
List<Horse> matchingHorses = jdbcTemplate.query(sql, new Object[]{horse.getName()}, mapHorse());
This returns a correct result but I have to pass to new Object[] {}
only the parameters that I know that user is gonna pass or else I do not get anything. For example if user passes something like this:
{
"description":"desc"
}
I won't get any results even if there is a description
with "desc". If I do this:
List<Horse> matchingHorses = jdbcTemplate.query(sql, new Object[]{horse.getName(), horse.getDescription(), horse.getRating()}, mapHorse());
and pass only name I get:
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]
Here is my mapHorse()
row mapper:
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,
);
};
}
How do I implement this correctly?
Upvotes: 2
Views: 10896
Reputation: 111
You can use 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());
suggestion- better if you you use string builder.
Upvotes: 1