Migrando la lista de ventas a Hibernate en nuestra aplicación PrimeFaces/JSF/Spring/Hibernate

Hola gente,

seguimos con nuestra aplicación, en esta ocasión migraremos la obtención de la lista de ventas para que sea manejada por Hibernate.

Objetivo

Utilizar la capacidad de trabajar con consultas sql nativas parametrizadas de Hibernate.

Desarrollo

En esta ocasión no es mucho el trabajo, comenzaremos configurando:

ar.com.magm.web.primefaces.VentasBean

...
...

SessionFactory sessionFactory; 

public VentasBean() {
  jsfCtx = FacesContext.getCurrentInstance();
  bundle = jsfCtx.getApplication().getResourceBundle(jsfCtx, "msg");
  sessionFactory = HibernateUtil.getSessionFactory(); 
  // processList(null);
}

...
...

Solo agregamos una instancia de SessionFactory para poder trabajar con Hibernate en las instancias de esta clase.
Luego debemos modificar el método que genera la lista de ventas:

private void processList(Object args[]) {
  meses = bundle.getString("lbl.months").split(",");
  ventas = new ArrayList<Venta>();
  zonas = new ArrayList<String>();
  Session session = sessionFactory.getCurrentSession();
  Query query = session.createSQLQuery(sql);
  if (args != null) {
    for (int t = 0; t < args.length; t++) {
      query.setParameter(0, args[t]);
    }
  }
  List<Object[]> vtaTmp = query.list();
  for (Object[] vo : vtaTmp) {
    Venta venta = new Venta(vo[2].toString(), 
                            vo[3].toString(),
                            Integer.parseInt(vo[0].toString()),
                            Integer.parseInt(vo[1].toString()),
                            meses[Integer.parseInt(vo[1].toString()) - 1],
                            Double.parseDouble(vo[4].toString()));
    ventas.add(venta);
    if (!zonas.contains(venta.getZona()))
      zonas.add(venta.getZona());
  }

  /*
  ServletContext sc = (ServletContext) FacesContext.getCurrentInstance()
                                        .getExternalContext().getContext();
  Connection cn = (Connection) sc.getAttribute("datasource");
  try {
    PreparedStatement pst = cn.prepareStatement(sql);
    if (args != null) {
      for (int t = 0; t < args.length; t++) {
        pst.setObject(t + 1, args[t]);
      }
    }
    ResultSet rs = pst.executeQuery();
    while (rs.next()) {
      String zona = rs.getString("zona");
      Venta venta = new Venta(zona, rs.getString("cliente"), rs.getInt("anio"),          
                              rs.getInt("mes"), meses[rs.getInt("mes") - 1], 
                              rs.getDouble("ventas"));
      ventas.add(venta);
      if (!zonas.contains(zona))
        zonas.add(zona);
    }
  } catch (SQLException e) {
    e.printStackTrace();
  }
  */
}

Lo primero que haremos en este método es inhabilitar todo el código antiguo, en aquel en que utilizábamos JDBC. Se puede ver que hemos utilizado comentarios de bloque: /* .. */
Luego en la línea
Query query = session.createSQLQuery(sql);
Obtenemos un objeto Query, el cual nos permite trabajar con sentencias SQL nativas, el método recibe como parámetro la consulta, que no es ni más ni menos que la que ya estábamos utilizando:

SELECT 
  year(fecha) as anio, 
  month(fecha) as mes, 
  zona, 
  cliente, 
  sum(importe*cantidad) as ventas 
FROM 
  dw_ventasfact v 
    INNER JOIN clientes c ON v.idCliente=c.idCliente 
    INNER JOIN zonas z ON z.idZona=c.idZona 
WHERE 
  cliente like ? 
GROUP BY 
  zona, cliente, anio, mes 
ORDER BY 
  anio,mes,zona,cliente
En el siguiente fragmento establecemos los valores para los parámetros, la diferencia más importante con el método anterior es que los parámetros comienzan desde 0, en JDBC es a partir de 1.
if (args != null) {
  for (int t = 0; t < args.length; t++) {
    query.setParameter(0, args[t]);
  }
}
En la líneaList<Object[]> vtaTmp = query.list();
obtenemos una lista que en cada elemento contiene un arreglo de objetos que representa una fila, en nuestro caso una entidad de ventas. El orden de los elementos del array coinciden con lo definido en la consulta SQL, en nuestro caso: 
[0]=año
[1]=mes
[2]=zona
[3]=cliente
[4]=ventas

El código que sirve para poblar la lista (el ciclo while) casi no ha cambiado, solo se reemplazó la línea que instancia la venta, ahora se utilizan los elementos del array y también se reutiliza la zona ya obtenida, por ello se quitó la primera línea en la cual se obtenía.

 
Esta es toda la modificación que hay que realizar en cuanto a código, ahora solo falta crear sesiones para que puedan ser utilizadas en este componente para lo cual modificaremos HibernateContextListenerAndFiltercomo ya lo hemos hecho antes:
 
...
@WebFilter(urlPatterns = { "/TestHibernateConSpring", "*.xhtml" }) 
...
 
Solo agregamos el patrón "*.xhtml" para que se creen sesiones ante peticiones de componentes JSF.
 
Bien, ya podemos probar y no notaremos ninguna diferencia, todo seguirá funcionando como antes del lado del cliente, solo que ahora Hibernate maneja algo más. En la consola podemos ver las sentencias SQL que Hibernate envía al motor.
 
Espero les sea de utilidad
 
Saludos
 

 

 

Enviar un comentario nuevo

El contenido de este campo se mantiene como privado y no se muestra públicamente.

Si no estás registrado recuerda que tu comentario entrará en una cola de aprobación.

Más información sobre opciones de formato

Enviando este formulario, acepta la política de privacidad de Mollom.

 



 

  BI   |    CRM     |    CMS    |    Tendencias en software empresarial    |    Cloud computing  |    Software libre    |   Internet    |    Movilidad y apps