我正在尝试实现一个int-jdbc:stored-proc-outbound-gateway,它使用高级oracle类型IN参数执行oracle存储过程。
我不清楚如何为IN参数声明高级类型。
代码和配置如下所示。
create or replace PROCEDURE POC2
(
D_LIST IN MOVE_AUDIT,
DB_RESPONSE OUT VARCHAR2)
IS
BEGIN
.....
END POC2;
create or replace TYPE MOVE_AUDIT IS OBJECT
(
MOVE_ID VARCHAR2(50),
MESSAGE VARCHAR2(50)
);
create or replace TYPE MOVE_AUDIT_TAB IS TABLE OF MOVE_AUDIT;
stored-proc-outbound-gateway配置:
<int-jdbc:stored-proc-outbound-gateway
id="inParamStorprocGateway" data-source="dataSource"
request-channel="requestChannel" is-function="false"
reply-channel="replyChannel" stored-procedure-name="POC2"
expect-single-result="false" ignore-column-meta-data="true">
<int-jdbc:sql-parameter-definition
name="D_LIST" direction="IN" type="STRUCT" type-name="MOVE_AUDIT_TAB" return-type="sqlReturnStruct"/>
<int-jdbc:sql-parameter-definition name="DB_RESPONSE" direction="OUT" type="VARCHAR"/>
<int-jdbc:parameter name="D_LIST" expression="payload"/>
</int-jdbc:stored-proc-outbound-gateway>
<bean id="sqlReturnStructArrayConfirmPutway" class="org.springframework.data.jdbc.support.oracle.SqlReturnStructArray">
<constructor-arg name="mapper" ref="confirmPutawayStructMapper"/>
</bean>
<bean id="confirmPutawayStructMapper" class="com.test.mapper.ConfirmDomainStructMapper"/>
Bellow是结构Mapper:
public class ConfirmDomainStructMapper implements StructMapper<ConfirmDomain> {
public STRUCT toStruct(ConfirmDomain oDemoDomainObject, Connection conn, String typeName)
throws SQLException {
StructDescriptor descriptor = new StructDescriptor(typeName, conn);
Object[] values = new Object[2];
values[0] = oDemoDomainObject.getId();
values[1] = oDemoDomainObject.getName();
return new STRUCT(descriptor, conn, values);
}
public ConfirmDomain fromStruct(STRUCT struct) throws SQLException {
ConfirmDomain oDemoDomainObject=null;
if(null!=struct){
oDemoDomainObject=new ConfirmDomain();
Datum[] resArray=struct.getOracleAttributes();
oDemoDomainObject.setId(resArray[0].stringValue());
oDemoDomainObject.setName(resArray[1].stringValue());
}
return oDemoDomainObject;
}
}
我尝试并调试了这段代码,但它没有调用StructMapper的toStruct方法。
从日志中我得到的D_LIST传递为NULL
答案 0 :(得分:1)
首先,由于以下原因,我根本不了解您的应用运行情况:
else {
parameterBuilder = BeanDefinitionBuilder.genericBeanDefinition(SqlParameter.class);
if (StringUtils.hasText(returnType)) {
parserContext.getReaderContext().error("'return-type' attribute can't be provided " +
"for IN 'sql-parameter-definition' element.", storedProcComponent);
}
}
因此,return-type
只能为OUT
参数指定。
proc定义的另一个问题。我猜它应该有D_LIST IN TYPE MOVE_AUDIT_TAB
,因为,我认为,你将同时存储几个对象。
所以,忘掉return-type
和那个ConfirmDomainStructMapper
,当你想阅读OUT
参数时,它就会出现。
只有当您的<int-jdbc:parameter name="D_LIST" value="payload"/>
确实是该自定义Oralce类型的对象时,此payload
才会生效。
从Java角度来看,IS TABLE OF
类型称为ARRAY
。所以你真的应该使用一些Oracle JDBC本机代码来创建它。
我曾经这样做过,看起来像是:
<transformer expression="@oracleArrayCreator.create(payload, '${scheme.name}.MOVE_AUDIT_TAB', '${scheme.name}.MOVE_AUDIT')"/>
请注意,这些类型必须在任何包装之外。否则Oracle JDBC驱动程序无法解决它们。
@Service
@org.springframework.context.annotation.Lazy
class OracleArrayCreator {
@Autowired
DataSource dataSource
@Autowired
Properties internalProperties
ARRAY create(List<Map> data, String tableName, String recordName) {
def recordKeys = internalProperties.getProperty(recordName.replaceFirst(/.*\./, '')).split(',')
def connection = nativeConnection
def structDescriptor = StructDescriptor.createDescriptor(recordName, connection)
def dataArray = []
data.each { recordMap ->
def record = []
if (recordMap) {
recordKeys.each {
record << recordMap[it]
}
dataArray << new STRUCT(structDescriptor, connection, record.toArray())
}
}
new ARRAY(ArrayDescriptor.createDescriptor(tableName, connection), connection, dataArray.toArray())
}
ARRAY create(Map data, String tableName, String recordName) {
create([data], tableName, recordName)
}
CLOB convertToClob(String value) {
CLOB c = CLOB.createTemporary(nativeConnection, false, CLOB.DURATION_SESSION)
c.setString(1L, value)
return c
}
Connection getNativeConnection() {
DataSourceUtils.getConnection(dataSource).metaData.connection
}
}
(抱歉Groovy代码)。
并将<transformer>
放在<int-jdbc:stored-proc-outbound-gateway>
之前。当然,您可以将它们都包装到<chain>
。
是的,type="ARRAY"
应该是D_LIST
param。
答案 1 :(得分:0)
频繁阻塞线程
要获得连接,我正在使用
Connection conn=DataSourceUtils.getConnection(datasource);
并发布: 最后一个块中的
DataSourceUtils.releaseConnection(conn);
一个线程。
http-/0.0.0.0:8081-73
oracle.sql.TypeDescriptor.getName(TypeDescriptor.java:682)
oracle.jdbc.oracore.OracleTypeCOLLECTION.isInHierarchyOf(OracleTypeCOLLECTION.java:149)
oracle.jdbc.driver.OraclePreparedStatement.processCompletedBindRow(OraclePreparedStatement.java:2063)
oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3579)
oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3685)
oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4714)
oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1376)
sun.reflect.GeneratedMethodAccessor96.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
net.bull.javamelody.JdbcWrapper.doExecute(JdbcWrapper.java:403)
net.bull.javamelody.JdbcWrapper$StatementInvocationHandler.invoke(JdbcWrapper.java:128)
net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:285)
com.sun.proxy.$Proxy64.execute(Unknown Source)
另一个
http-/0.0.0.0:8081-71
oracle.sql.ARRAY.toBytes(ARRAY.java:675)
oracle.jdbc.driver.OraclePreparedStatement.setArrayCritical(OraclePreparedStatement.java:5985)
oracle.jdbc.driver.OraclePreparedStatement.setARRAYInternal(OraclePreparedStatement.java:5944)
oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:8782)
oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8278)
oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8877)
oracle.jdbc.driver.OracleCallableStatement.setObject(OracleCallableStatement.java:4992)
oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:240)
sun.reflect.GeneratedMethodAccessor105.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)