问题 如何在Spring JDBC中组合多个参数源?


Spring JDBC中的数据库方法接受单个参数源。例如 -

int org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(String sql, SqlParameterSource paramSource) throws DataAccessException

是否可以将多个参数源组合在一起?例如,假设我有一个bean Order  -

class Order {
int id;
float price;
int customerId;
Date date;
//Lots of other fields
}

我想用一些额外的字段来保存这个bean recordModificationTime 和 accessLevel

如果我使用 MapSqlParameterSource 对于存在于bean之外的这些额外字段,我无法使用 BeanPropertySqlParameterSource 因为该方法只接受一个参数源。必须使用 MapSqlParameterSource 对于我的所有数据意味着我必须手动提取所有bean属性,这是很多工作。

处理这个问题的最佳方法是什么?


12033
2017-11-12 06:19


起源



答案:


你可以扩展 AbstractSqlParameterSource 并聚合BeanProperty和Map版本:

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);
  }
}

现在使用它像这样:

CombinedSqlParameterSource mySource = new CombinedSqlParameterSource(myOrder);
mySource.addValue("recordModificationTime", time);
mySource.addValue("accessLevel", level);

jdbcTemplate.update(sql, mySource);

15
2017-11-12 09:37



谢谢@dei,更改了getValue上的返回类型。 - mrembisz


答案:


你可以扩展 AbstractSqlParameterSource 并聚合BeanProperty和Map版本:

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);
  }
}

现在使用它像这样:

CombinedSqlParameterSource mySource = new CombinedSqlParameterSource(myOrder);
mySource.addValue("recordModificationTime", time);
mySource.addValue("accessLevel", level);

jdbcTemplate.update(sql, mySource);

15
2017-11-12 09:37



谢谢@dei,更改了getValue上的返回类型。 - mrembisz