The database methods in Spring JDBC accept a single parameter source. For example -
int org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(String sql, SqlParameterSource paramSource) throws DataAccessException
Is it possible to combine multiple parameter sources together? For example, suppose I have a bean Order
-
class Order {
int id;
float price;
int customerId;
Date date;
//Lots of other fields
}
I want to save this bean with some additional fields like recordModificationTime
and accessLevel
.
If I use MapSqlParameterSource
for these extra fields which exist outside the bean, I cannot use BeanPropertySqlParameterSource
because the method accepts only one parameter source. Having to use MapSqlParameterSource
for all my data means I have to manually extract all the bean properties, which is a lot of work.
What is the best way to deal with this problem?
NamedParameterJdbcTemplate class is a template class with a basic set of JDBC operations, allowing the use of named parameters rather than traditional '?' placeholders. This class delegates to a wrapped JdbcTemplate once the substitution from named parameters to JDBC style '?' placeholders is done at execution time.
Functionally, there's no difference between Spring's JdbcTemplate and it's variant, NamedParameterJdbcTemplate except for : NamedParameterJdbcTemplate provides a better approach for assigning sql dynamic parameters instead of using multiple '?' in the statement.
Using the JdbcTemplate batch processing is accomplished by implementing a special interface, BatchPreparedStatementSetter , and passing that in as the second parameter in your batchUpdate method call. This interface has two methods you must implement.
NamedParameterJdbcTemplate wraps a JdbcTemplate to provide named parameters instead of the traditional JDBC "?" placeholders. This approach provides better documentation and ease of use when you have multiple parameters for an SQL statement.
You can extend AbstractSqlParameterSource
and aggregate both BeanProperty and Map versions:
public class CombinedSqlParameterSource extends AbstractSqlParameterSource {
private MapSqlParameterSource mapSqlParameterSource = new MapSqlParameterSource();
private BeanPropertySqlParameterSource beanPropertySqlParameterSource;
public CombinedSqlParameterSource(Object object) {
this.beanPropertySqlParameterSource = new BeanPropertySqlParameterSource(object);
}
public void addValue(String paramName, Object value) {
mapSqlParameterSource.addValue(paramName, value);
}
@Override
public boolean hasValue(String paramName) {
return beanPropertySqlParameterSource.hasValue(paramName) || mapSqlParameterSource.hasValue(paramName);
}
@Override
public Object getValue(String paramName) {
return beanPropertySqlParameterSource.hasValue(paramName) ? beanPropertySqlParameterSource.getValue(paramName) : mapSqlParameterSource.getValue(paramName);
}
@Override
public int getSqlType(String paramName) {
return beanPropertySqlParameterSource.hasValue(paramName) ? beanPropertySqlParameterSource.getSqlType(paramName) : mapSqlParameterSource.getSqlType(paramName);
}
}
And now use it like this:
CombinedSqlParameterSource mySource = new CombinedSqlParameterSource(myOrder);
mySource.addValue("recordModificationTime", time);
mySource.addValue("accessLevel", level);
jdbcTemplate.update(sql, mySource);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With