これが私が取った別のアプローチです。ユーザーが通話で提供するパラメーターの数を設定できる機能を追加しました。これらは、最初の n 個の定位置パラメーターになります。ストアド プロシージャで使用可能な残りのパラメーターは、データベースの既定値の処理を介して設定する必要があります。これにより、値を提供することを知らないコードを壊すことなく、新しいパラメーターをデフォルト値でリストの最後に追加したり、null 可能にすることができます。
SimpleJdbcCall をサブクラス化し、「maxParamCount」を設定するメソッドを追加しました。また、サブクラス化されたバージョンの CallMetaDataContext を設定するために、少し邪悪なリフレクションを使用しました。
public class MySimpleJdbcCall extends SimpleJdbcCall
{
private final MyCallMetaDataContext callMetaDataContext = new MyCallMetaDataContext();
public MySimpleJdbcCall(DataSource dataSource)
{
this(new JdbcTemplate(dataSource));
}
public MySimpleJdbcCall(JdbcTemplate jdbcTemplate)
{
super(jdbcTemplate);
try
{
// Access private field
Field callMetaDataContextField = AbstractJdbcCall.class.getDeclaredField("callMetaDataContext");
callMetaDataContextField.setAccessible(true);
// Make it non-final
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(callMetaDataContextField, callMetaDataContextField.getModifiers() & ~Modifier.FINAL);
// Set field
callMetaDataContextField.set(this, this.callMetaDataContext);
}
catch (NoSuchFieldException | IllegalAccessException ex)
{
throw new RuntimeException("Exception thrown overriding AbstractJdbcCall.callMetaDataContext field", ex);
}
}
public MySimpleJdbcCall withMaxParamCount(int maxInParamCount)
{
setMaxParamCount(maxInParamCount);
return this;
}
public int getMaxParamCount()
{
return this.callMetaDataContext.getMaxParamCount();
}
public void setMaxParamCount(int maxInParamCount)
{
this.callMetaDataContext.setMaxParamCount(maxInParamCount);
}
}
私の CallMetaDataContext サブクラスでは、maxInParamCount を保存し、それを使用して、ストアド プロシージャに存在することがわかっているパラメーターのリストをトリミングします。
public class MyCallMetaDataContext extends CallMetaDataContext
{
private int maxParamCount = Integer.MAX_VALUE;
public int getMaxParamCount()
{
return maxParamCount;
}
public void setMaxParamCount(int maxInParamCount)
{
this.maxParamCount = maxInParamCount;
}
@Override
protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters)
{
List<SqlParameter> limittedParams = new ArrayList<>();
int paramCount = 0;
for(SqlParameter param : super.reconcileParameters(parameters))
{
if (!param.isResultsParameter())
{
paramCount++;
if (paramCount > this.maxParamCount)
continue;
}
limittedParams.add(param);
}
return limittedParams;
}
}
パラメータの最大数を確認する以外は基本的に使い方は同じです。
SimpleJdbcCall call = new MySimpleJdbcCall(jdbcTemplate)
.withMaxParamCount(3)
.withProcedureName("MayProc");
小さな暴言: Spring が IOC コンテナーでよく知られているのは面白いことです。しかし、そのユーティリティ クラス内では、リフレクションに頼って依存クラスの代替実装を提供する必要があります。