Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine multiple parameter sources in Spring JDBC?

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?

like image 672
Kshitiz Sharma Avatar asked Nov 12 '12 06:11

Kshitiz Sharma


People also ask

What is the advantage of NamedParameterJdbcTemplate?

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.

What is difference between Namedjdbctemplate and JdbcTemplate?

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.

How does JdbcTemplate batchUpdate works?

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.

Which approach provides better documentation and ease of use when you have multiple parameters?

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.


1 Answers

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);
like image 63
mrembisz Avatar answered Oct 05 '22 12:10

mrembisz