gpt4 book ai didi

java - 使用 spring StoredProcedure 将参数输出为 Integer

转载 作者:行者123 更新时间:2023-12-02 00:47:30 27 4
gpt4 key购买 nike

我试图将 Oracle 存储过程的输出参数存储在我的变量中,但遇到了这个问题:

java.math.BigDecimal cannot be cast to java.lang.Integer

我正在使用StoredProcedure来自org.springframework.jdbc.object返回 Map<String, Object> 的执行方法然后我做了这样的事情

Integer proposalId = procedure.execute().get("po_proposal_id");

其中 po_proposal_id 在 PROCEDURE 中定义为

po_proposal_id          Out Number,

我知道我可以做这样的事情:

Integer proposalId = ((BigDecimal) 
procedure.execute().get("po_proposal_id")).intValue();

但我不想。我为什么要那么做? Spring StoredProcedure 中的执行方法是否始终将 Number SQL 参数映射为 BigDecimal?

我尝试将过程中的参数声明为

po_proposal_id          Out Integer,

但运气不佳。

我还尝试更改 Java 中输出参数从 oracle.types.Number 映射到 oracle.types.Integer 的方式,但没有成功。

我找到了这张表Table 3-1 SQL and PL/SQL Data Type to Oracle and JDBC Mapping Classes (你需要向下滚动一点)显示了 oracle 数据类型和 java 之间的映射,但似乎我无法让它工作。

最佳答案

嗨,格罗吉亚, 我将尝试回答我对Spring StoredProcedure类做了一些无聊的分析,当你调用StoredProcedure类的execute方法时,它调用下面的方法

getJdbcTemplate().call(newCallableStatementCreator(inParams), getDeclaredParameters())

经过一系列调用后,它最终调用 ResultSet 类的 getObject(int column index) 方法,该方法依赖于 oracle 的数据库提供程序,mysql 完全不同,该方法负责返回对象的数据类型由列行映射器调用,该映射器映射每个列名称的列以及使用 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 类型 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,它指定您需要存储过程中的一些输出参数列表,并且它对数据类型没有影响。

关于java - 使用 spring StoredProcedure 将参数输出为 Integer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57885670/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com