martes, 20 de agosto de 2013

Ejecutar procedimiento almacenado en hibernate 4

De vez en cuando hay que ejecutar procedimiento almacenados en hibernate 4 he aqui un ejemplo, en realidad utiliza hibernate como la capa mas alta, al final lo ejecuta por jdbc, y esto es porque hibernate 4 solo ejecuta procedimientos almacenados de forma directa si estos devuelven datos en plan resultset, en caso contrario segun nos cuenta en su pagina se debe de utilizar por jdbc, que le llaman un "Work"

Ejemplo:

Params es una clase para encapsular lo datos entrada salida.

public void executeProcedimientoAlmacenado(final Params params) {
final StringBuilder sql = new StringBuilder("");
sql.append(" call esquema.nombre_procedimiento_almacenado(");
sql.append(" ?,");//IN_param_1
sql.append(" ?,");//IN_param_2
sql.append(" ?)");//OUT_param_1
getSession().doWork(new Work(){

public void execute(Connection connection) throws SQLException {
CallableStatement callStmt = connection.prepareCall(sql.toString());
int indexParam=1;
callStmt.setInt(indexParam++, params.getInParam_1());//1
    callStmt.setInt(indexParam++, params.getInParam_2() !=null ? params.getInParam_2() : Types.NULL);//2
callStmt.registerOutParameter(indexParam++, Types.INTEGER);//3
callStmt.executeUpdate();

params.setOutParam(callStmt.getInt(3)); //El parametro 3 es la salida, y lo pasamos al objecto params
}

});
}

Como se ve se utiliza "Work" que es una ejecución directa jdbc encampsulada por hibernate 4, y el objeto Params contiene los datos de entrada posterioremente se setean los de salida y así desde donde se llama el método el params contiene los resultados.

el getSession() es para obtener la session de hibernate, que se traduce también en sessionFactory.getSession() el sessionFactory es inyectado con Spring al Dao que ejecute los procedimientos almacenados, igual que cualquier otro dao.


viernes, 16 de agosto de 2013

Ejecutar procedumiento almacenado de DB2 en DbVisualizer Free 9.0.8

DbVisualizer es gratis, pero tiene muchas limitaciones la version gratuita :( y como siempre los empresarios se niegan a pagar las licencias de todas las utilerias que necesarias para realizar sistemas de manera mas agil. Si no queremos usar la linea de comandos de DB2 podemos ejecutar lo siguiente en el DbVisualizer:

@call esquema.nombre_procedimiento_almacenado(param1, param2, ${nomVar||(null)||Date||dir=out}$);

se utiliza el @call para ejecutar el procedimiento almacenado
las variables de entrada van directamente en los parametros.
Cuando es variable de salida se le especifica, lo que esta entre ${.....}$ indica que es una variable y se compone de 4 parametros:
nomVar, nombre de la variable cualquier.
(null), se especifica el valor, ya que es variable de salida, se pone a null.
Date, Es el tipo, puede ser Integer, String, BigInteger, etc....
dir, indica si es entrada "in", salida "out" o entrada salida "inout"

Cuando se ejecuta el procedimiento almacenado nomVar guarda el valor y luego para ver su valor se ejecuta:

@echo nomVar: ${nomVar}$;

y se muestra un popup con su valor.


jueves, 1 de agosto de 2013

Utileria. Convertir un DTO en String.


Aveces hace falta para sacar en consola o en el log, los valores de un objeto

    /**
     * Transforma un DTO a cadena.
     * @param obj
     * @return
     * @throws SecurityException 
     * @throws NoSuchMethodException 
     */
    public static String dtoToString(Object obj){
    if(obj!=null){
    StringBuilder out = new StringBuilder();
        out.append("[");
        Field[] props = obj.getClass().getDeclaredFields();
        for(Field prop:props){
    try{
    String methodName= "get";
        methodName += String.valueOf(prop.getName().charAt(0)).toUpperCase();
    methodName += prop.getName().substring(1);
    Method getter = obj.getClass().getMethod(methodName);
    Object value = getter.invoke(obj, new Object[0]);
        out.append(prop.getName()+":"+value);
        out.append(", ");
    }catch(Exception e){
    }    
        }
        out.append("]");
        return out.toString();
    }else{
    return "No dto object";
    }
    }


Utileria. Para poblar un pojo con datos provenientes de un resultSet.

Esta es una clase utileria para poblar un objeto DTO con datos provenientes de un resultset en java

package com.inditex.isu4.core.services.factory;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;

/**
 * Factoria de construccion de DTO's
 * @author etereum
 *
 */
public class DTOFactory{

private static Logger log = Logger.getLogger(DTOFactory.class);

/**
* Contrulle la lista de DTO's apartir del tipo de dto que se pase como parametro.
* @param dtoType
* @param rs
* @return
* @throws SQLException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws SecurityException
*/
public static <T> List<T> getDTOListFromRS(T dtoType, ResultSet rs) throws SQLException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException{
log.debug("getDTOListFromRS....");
List<T> dataList = new ArrayList<T>();
Constructor[] factories = dtoType.getClass().getDeclaredConstructors();
Constructor factory = null;
for (int i = 0; i < factories.length; i++) {
factory = factories[i];
   if (factory.getGenericParameterTypes().length == 0)
break;
}
while(rs.next()){
   Object dto = factory.newInstance();
   Field[] props = dto.getClass().getDeclaredFields();
  for(Field prop:props){
 try{
Object value = rs.getObject(prop.getName());
  String methodName= "set";
      methodName += String.valueOf(prop.getName().charAt(0)).toUpperCase();
  methodName += prop.getName().substring(1);
  Class<?> classType =null;
  if(value ==null){
  continue;
  }else if(value instanceof String){
      classType=String.class;
  }else if(value instanceof Integer){
      classType=Integer.class;
  }else if(value instanceof Date){
  classType=Date.class;
  }
  Method setter = dto.getClass().getMethod(methodName, classType);
  setter.invoke(dto, value);
 }catch(Exception e){
 log.warn("No fue posible asignar el valor. ["+prop+"]");
   log.warn("Exception.getDTOListFromRS", e);
   }
           }
dataList.add((T)dto);
}
log.debug("getDTOListFromRS.OK.");
return dataList;
}

}