martes, 9 de agosto de 2011

Como llamar un package que tiene un cursor de entrada y salida desde spring con jdk142_11 (la vieja escuela)

Lo primero que debemos crear es una clase que herede las propiedades de la clase StoredProcedure, dentro de ella definimos la llamada al package de la manera que más les acomode, en el ejemplo les dejo una forma que recomiendo (recordando que no soy dueño de la verdad y si algún lector considera que existe algo mejor le agradecería comentarlo).

public class GetNotiPortal extends StoredProcedure

{

private static final String SPROC_NAME = "Ruta con el Package";

public GetNotiPortal(DataSource ds)

{

super(ds,SPROC_NAME);

declareParameter(new SqlParameter("Parametro1", OracleTypes.VARCHAR));

declareParameter(new SqlParameter("Parametro2",OracleTypes.VARCHAR));

declareParameter(new SqlOutParameter("OUT_CURSORPORTAL ", OracleTypes.CURSOR,new ClaseRowMapper()));

compile();

}

}

Dentro del método GetNotiPortal se hace una llamada al constructor de la clase de la que se hereda (extends), pasándole dos parámetros (Datasource y un String), luego de esto debemos declarar los parámetros de entrada en este caso son dos más la declaración del Cursor definiéndolo con su respectiva clase RowMapper ya que debemos recordar que no es solo un parámetro de entrada si no que cumple doble función.

La siguiente función nos permite ejecutar el package y leer el cursor que contiene la información de salida.

public Resultado[] recuperaDatos(String valor1, String valor2)

{

Resultado[] resultado = null;

GetNotiPortal getNotiPortal = new GetNotiPortal(this.getDataSource());

Map inParams = new HashMap();

inParams.put("Parametro1", valor1);

inParams.put("Parametro2", valor2);

Map results = getNotiPortal.execute(inParams);

if (results.get("OUT_CURSORPORTAL")==null)

{

return resultado;

}

else

{

Set s=results.entrySet();

Iterator it=s.iterator();

while(it.hasNext())

{

Map.Entry m =(Map.Entry)it.next();

Object o = m.getValue();

List l = (List)o;

resultado = new NotificaVo[l.size()];

for (int i=0; i < l.size(); i++)

{

resultado[i]= (NotificaVo)l.get(0);

}

}

return notificaVo;

}

}

Definición de datasource y Rowmapper en el applicationContext.xml

Los datasource y las clases Rowmapper en spring deben definirse dentro del archivo applicationContext.xml de la siguiente manera.

<bean id="Datasource"

class="org.springframework.jndi.JndiObjectFactoryBean">

<property name="jndiName" value="ds/Datasource" />

bean>

<bean id="txManagerDatasource"

class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="Datasource" />

bean>

<bean id="serviceDatasource"

class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

<property name="transactionManager" ref="txManagerProdSaludNew" />

<property name="target" ref="gestionadorSolicitud" />

<property name="transactionAttributes">

<props>

<prop key="recuperar*">

PROPAGATION_SUPPORTS,readOnly

prop>

<prop key="*">PROPAGATION_REQUIREDprop>

props>

property>

bean>

<bean id="claseRowMapper"

class="package.dao.utils.claseRowMapper">

bean>

<bean id="Nombredelaclase"

class="package.dao.Nombredelaclase ">

<property name="dataSource">

<ref bean="Datasource" />

property>

<property name="claseRowMapper">

<ref bean="claseRowMapper" />

property>

bean>

* El datasource debe estar creado y definido con los mismos parámetros en el servidor.

Ejemplo de Clase Rowmapper

public class ClaseRowMapper implements RowMapper{

public Object mapRow(ResultSet rs, int rowNum) throws SQLException{

ClaseVo claseVo = null;

int id = 0;

if((id = rs.getInt(2)) != 0)

{

claseVo = new NotificaVo();

claseVo.setnum(new Integer(id));

claseVo.setstring(rs.getString(1));

claseVo.setstring(rs.getString(2));

}

return claseVo;

}

}