这是我采取的另一种方法。我添加了让用户设置他们将在通话中提供的参数数量的功能。这些将是前 n 个位置参数。存储过程中可用的任何剩余参数都必须通过数据库的默认值处理进行设置。这允许使用默认值将新参数添加到列表的末尾,或者可以为空,而不会破坏不知道提供值的代码。
我对 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");
SMALL RANT:有趣的是,Spring 以其 IOC 容器而闻名。但是,在它的实用程序类中,我不得不求助于反射来提供依赖类的替代实现。