martes, abril 09, 2013

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 HibernateContextListenerAndFilter como 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



Como siempre el proyecto completo y el WAR en el repo de GITHUB: https://github.com/magm3333/workspace-pftuto



Saludos

Mariano

Publicar un comentario

Seguirme por email

Etiquetas

pentaho (45) java (35) eclipse (23) jdbc (14) curso (13) tomcat (13) primefaces (12) db2 (11) mondrian (10) review (10) jsf (9) openI (9) pdi (9) prd (9) libro (8) plugin (8) musql (7) struts (7) javascript (6) spring (6) cdf (5) ctools (5) instalar (5) linux (5) mysql (5) data studio (4) hibernate (4) ireport (4) jasper (4) meteor (4) videocurso (4) eglu (3) eglubi (3) elearning (3) graphite (3) grupo eglu (3) jboos tools (3) mexico (3) openbits (3) packt (3) python (3) undec (3) websphere (3) applet (2) cde (2) dao (2) db2university (2) exelearning (2) flexigrid (2) hadoop (2) iua (2) kettle (2) moodle (2) node (2) olap (2) osbi (2) pivot4j (2) scorm (2) sql (2) stpivot (2) actionscript (1) amazon (1) autenticacion (1) avanzado (1) base de datos (1) big data (1) bigdata (1) bodoc (1) cambiar (1) ccc (1) cdc (1) chat (1) cloud (1) coffeescript (1) control de acceso (1) corti (1) csv (1) cuba (1) curso meteor undec (1) dashboard (1) datamart (1) dataptix.tv (1) datasource (1) datatable (1) db2 ExpressC (1) demonio (1) distancia (1) driver (1) driver jdbc (1) eglufiltertwolist (1) encapsulamiento (1) especialización (1) etl (1) excepciones (1) export (1) faces (1) federación (1) filas afectadas (1) filtertwolist (1) filtrado (1) flegrid (1) flex (1) google (1) google viz (1) hostname (1) html (1) i18n (1) ibm (1) identidad (1) indignación (1) instancias (1) inteligencia de negocios (1) jee (1) jpivot (1) l10n (1) la azada (1) la zaga de los confines (1) layout (1) liberado (1) libre (1) libro promoción (1) lob (1) marktplace (1) menu (1) meteor node javascript google oauth autenticacion (1) mobile (1) mongoDB (1) node.js (1) oauth (1) olap4j (1) open source (1) orm (1) persistencia (1) personalizada (1) prd5 (1) psw (1) publicidad (1) rad6 (1) recursividad (1) reporting (1) rock (1) saiku (1) script (1) servicio (1) sessiontimeout (1) sourceforge (1) spinneta (1) sqlserver (1) ssl (1) taller (1) troyanx (1) ubuntu (1) ucc (1) ui (1) web (1) web console (1) xampp (1) xml (1) xpath (1)

Seguidores