你好格罗吉亚,
我会试着回答当你调用StoredProcedure类的execute方法时我对Spring StoredProcedure类做了一些无聊的分析它调用了下面的方法
getJdbcTemplate().call(newCallableStatementCreator(inParams), getDeclaredParameters())
经过一系列的调用,它最终调用了ResultSet类的getObject(int column index)方法,该方法是Oracle依赖的Database provider,mysql完全不同,该方法负责返回对象的数据类型,这是由 Column Row Mapper 调用,它映射每个列名的列,并且使用 StoredProcedure 类的相应值
**Column Row Mapper Class :**
@Override
public Map<String, Object> mapRow(ResultSet rs, int rowNum) throws SQLException {
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
Map<String, Object> mapOfColumnValues = createColumnMap(columnCount);
for (int i = 1; i <= columnCount; i++) {
String column = JdbcUtils.lookupColumnName(rsmd, i);
mapOfColumnValues.put(getColumnKey(column), getColumnValue(rs, i));
}
return mapOfColumnValues;
}
getColumnValue(rs, i) 负责调用getResultSetValue(ResultSet rs, int index) 方法,该方法负责调用resultSet 的getObject(int column index) 方法,实际决定返回的数据类型。
代码示例:
public static Object getResultSetValue(ResultSet rs, int index) throws SQLException {
Object obj = rs.getObject(index);
String className = null;
if (obj != null) {
className = obj.getClass().getName();
}
if (obj instanceof Blob) {
Blob blob = (Blob) obj;
obj = blob.getBytes(1, (int) blob.length());
}
else if (obj instanceof Clob) {
Clob clob = (Clob) obj;
obj = clob.getSubString(1, (int) clob.length());
}
else if ("oracle.sql.TIMESTAMP".equals(className) || "oracle.sql.TIMESTAMPTZ".equals(className)) {
obj = rs.getTimestamp(index);
}
else if (className != null && className.startsWith("oracle.sql.DATE")) {
String metaDataClassName = rs.getMetaData().getColumnClassName(index);
if ("java.sql.Timestamp".equals(metaDataClassName) || "oracle.sql.TIMESTAMP".equals(metaDataClassName)) {
obj = rs.getTimestamp(index);
}
else {
obj = rs.getDate(index);
}
}
else if (obj instanceof java.sql.Date) {
if ("java.sql.Timestamp".equals(rs.getMetaData().getColumnClassName(index))) {
obj = rs.getTimestamp(index);
}
}
return obj;
}
所以回到实际的问题,为什么只有它返回的 BigDecimal Type ResultSet 类的 getObject(int column index) 方法正在为 oracle 驱动程序调用以下方法
Datum var4 = this.getOracleObject(var1)
根据列的各个数据类型调用不同的访问器,并且每个访问器都在您的情况下实现了 getObject oracle 将所有数据类型(例如 int、float)视为数字数据类型参考 https://www.techonthenet.com/oracle/datatypes.php
所以它使用 NumberCommonAccessor,它总是为所有数据类型(如 int、float)返回 BigDecimal,所以你有显式类型转换,你会像往常一样收到数据类型 BigDecimal。它确实不依赖于 SqlOutParameter 来指定您需要存储过程中的一些输出参数列表,并且它对数据类型没有影响。