存储过程如下:
{#{FLAG,mode=OUT,jdbcType=DECIMAL} = call pkg_ly.f_ly
(#{P_LYDD,mode=IN,jdbcType=CLOB},
#{P_KHDH,mode=OUT,jdbcType=VARCHAR},
#{P_ERROR,mode=OUT,jdbcType=VARCHAR})}
出现问题的代码如下:
LogFilter类的下面这段代码有问题,请看加粗标记的地方
private void logExecutableSql(StatementProxy statement, String sql) {
if(this.isStatementExecutableSqlLogEnable()) {
int parametersSize = statement.getParametersSize();
if(parametersSize == 0) {
this.statementLog("{conn-" + statement.getConnectionProxy().getId() + ", " + this.stmtId(statement) + "} executed. \n" + sql);
} else {
ArrayList parameters = new ArrayList(parametersSize);
for(int dbType = 0; dbType < parametersSize; ++dbType) {
JdbcParameter formattedSql = statement.getParameter(dbType);
**//下面这行报错,formattedSql空指针异常**
parameters.add(formattedSql.getValue());
}
String var7 = statement.getConnectionProxy().getDirectDataSource().getDbType();
String var8 = SQLUtils.format(sql, var7, parameters);
this.statementLog("{conn-" + statement.getConnectionProxy().getId() + ", " + this.stmtId(statement) + "} executed. \n" + var8);
}
}
}
分析:
实际上入参只有1个,但是parametersSize等于2,原因如下:
PreparedStatementProxyImpl这个类的setParameter这个方法
void setParameter(int jdbcIndex, JdbcParameter parameter) {
int index = jdbcIndex - 1;
if(jdbcIndex > this.parametersSize) {
this.parametersSize = jdbcIndex;
}
if(this.parametersSize >= this.parameters.length) {
this.parameters = (JdbcParameter[])Arrays.copyOf(this.parameters, this.parametersSize + 16);
}
this.parameters[index] = parameter;
if(this.paramMap != null) {
this.paramMap = null;
}
}
由于入参是在第二个位置,所以jdbcIndex的值为2,最后parameterSize的值就为2,正常情况如果不是存储过程那么jdbcIndex是没有问题的。目前我在重写了logfilter类,解决,但是真正要解决的是在调用这个类的时候PreparedStatementProxyImpl要考虑存储过程的情况