style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

Patron DAO para consultas personalizadas

Hola a todos, les comento que estoy aprendiendo sobre la Persistencia en Java, aun soy novato en esto. Básicamente la duda que tengo es sobre como aplicar el patrón DAO, cuando se requiere mostrar un reporte particular sobre los datos de una base de datos, por ejemplo:

Base de datos
Supongamos que para una aplicación tenemos una base de datos con 3 tablas, con el fin de registrar la cantidad de productos comprada por cada cliente:

Clases para las Entidades
Luego, nuestras entidades correspondientes para las tablas serían:

public class Cliente
{
    private Integer ID;
    private String nombre;
       
    private Set<Venta> ventas = new HashSet<Venta>();
       
    // Getters, Setters y otros metodos
}

public class Venta
{
    private Cliente cliente;
    private Producto producto;
    private Integer cantidad;
       
    // Getters y Setters
}
public class Producto
{
    private Integer ID;
    private String nombre;
    private Double precio;

    private Set<Venta> ventas = new HashSet<Venta>();
       
    // Getters, Setters y otros metodos
}

Interfaces DAO
Ahora, definimos las interfaces para el patrón DAO:

  1. public interface ClienteDao {
  2.  
  3.     Cliente buscarUsuario( String nombre );
  4.      void insertarCliente( Cliente cliente );
  5.      void modificarCliente( Cliente cliente );
  6. }
  7.  
  8. public interface VentaDao {
  9.     // No interesa para el ejemplo
  10. }
  11.  
  12. public interface ProductoDao {
  13.     // No interesa para el ejemplo
  14. }

Reporte de ventas
Ahora supongamos que por caprichos de la vida, uno de los requerimientos es que el sistema muestre una tabla donde se resuma, la cantidad total de productos comprados y monto total de compra por cada cliente. Algo parecido a lo siguiente:

Siguiendo el patrón DAO
La inquietud que tengo es cuando deseo generar ese reporte. Siguiendo con la idea del patrón DAO, el código me queda algo parecido a esto:

  1. // Recuperar la factory apropiada para la implementación de los DAO's
  2. FactoryDao hibFactory = FactoryDao.getFactory( FactoryDao.HIB_FACTORY );
  3.  
  4. // Recuperar la implementación concreta para el DAO del cliente
  5. ClienteDAO clienteDAO = hibFactory.getClienteDao();
  6.  
  7. // Recuperar la lista de clientes registrados en la DB
  8. List<Cliente> clientes = clienteDAO.listarClientes();
  9.  
  10. Iterator<Cliente> iteratorCli = clientes.iterator();
  11.  
  12. while( iteratorCli.hashNext() )
  13. {
  14.     // Recuperar el siguiente cliente a mostrar en el reporte
  15.     cliente = iteratorCli.next();
  16.        
  17.     // Recuperar todas las ventas que se le hizo al cliente
  18.     Set<Venta> ventas = cliente.getVentas();
  19.        
  20.     Iterator<Venta> iteratorVen = ventas.iterator();
  21.                
  22.     while( iteratorVen.hashNext() )
  23.     {
  24.         // Recuperar la venta actual del cliente
  25.         venta = iteratorVen.next();
  26.                
  27.         // Recuperar el producto que se vendio
  28.         producto = venta.getProducto();
  29.                
  30.         // Monto que se pago por la venta del producto
  31.         monto = venta.getCantidad() * producto.getPrecio();
  32.                
  33.         // Añade una fila al reporte
  34.         // Nombre cliente   -  Nombre producto   -  Total venta
  35.         mostrarFila( cliente.getNombre(), producto.getNombre(), monto );
  36.     }
  37. }

La duda
Mi inquietud surge, luego de ver que para mostrar un reporte tan simple, se tuvo que hacer lo siguiente:

- Recuperar la lista de todos los clientes
- Por cada cliente recuperar la lista de todas las ventas en las que participa.
- Por cada venta del cliente, recuperar la información sobre el producto que se vendió

Creo que esa misma información se pudo haber recuperado con una consulta SQL, y estoy casi seguro de que la información se habría obtenido en un tiempo mucho más corto que con el código Java anterior.

SELECT
    nombreCli AS 'Nombre del cliente',
    nombrePro AS 'Nombre del producto',
    SUM( Cantidad * Costo ) AS 'Costo de venta'
FROM
    Cliente,
    Venta,
    Producto
WHERE
    Cliente.ID = Venta.ID_Cli AND
    Producto.ID = Venta.ID_Pro
GROUP BY
    nombreCli,
    nombrePro

Mi pregunta es: ¿Como aprovechar la velocidad de las consultas SQL para mostrar este tipo de reportes?
Lo primero que se me vino a la mente fue diseñar una interfaz para este tipo de reportes:

  1. public interface ReportesDAO
  2. {
  3.     // Recuperar los datos usando consultas SQL, retorna los datos en forma matricial
  4.     public Object[][] reporteVentasClientes();
  5.        
  6.     // Otros tipos muy particulares de reportes
  7. }
  8.  
  9.  
  10. // Recuperar la factory apropiada para la implementación de los DAO's
  11. FactoryDao hibFactory = FactoryDao.getFactory( FactoryDao.HIB_FACTORY );
  12.  
  13. // Recuperar la implementación concreta para proveedor de reportes
  14. ReportesDAO reportesDato = hibFactory.getReporteDAO();
  15.  
  16. // Recuperar el reporte de ventas de productos por cliente
  17. Object[][] reporte = reportesDato.reporteVentasClientes();
  18.  
  19. for( int i = 0; i < reporte.length; i ++ )
  20. {
  21.     mostrarFila( reporte[i][0], reporte[i][1], reporte[i][2] );
  22. }

Creo yo, que esto tiene un mejor rendimiento, pero no se si en un ambiente real de producción se use otro enfoque?, o como es que solucionan este tipo de problemas?, o yo estoy siendo paranoico con esto de la eficiencia?

Me gustaría que alguien que tenga experiencia en esto, me responda mis dudas por favor.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de neko069

Qué usas para mostrar tus

Qué usas para mostrar tus reportes? iReports? iText? porque de entrada iReports te puede ahorrar todo lo que haces, precisamente haciendo una consulta SQL, diseñas el reporte y lo muestras y ya, no tendrías que hacer todo ése rollo.
Si no usas nada y no tienes permitido agregar bibliotecas a tu proyecto, de todos modos puedes usar una consulta SQL, no es necesario/forzoso que uses Hibernate para absolutamente todo.

Imagen de XinefPro

Claro, pero a lo que me

Claro, pero a lo que me refiero es sobre:

- ¿Como encajaría la consulta SQL en el diseño del sistema?
- ¿Se tendría que crear una clase para cada reporte o poner todos los reportes dentro de una sola clase?
- ¿Es recomendable que los datos se recuperen en forma de una matriz de Objetcs?
- ¿Como es que se adaptaría este enfoque de usar consultas SQL con el patrón de diseño DAO?

Imagen de neko069

No

Si usas iReports, la consulta se crea dentro del mismo reporte, en el iReport Designer; si lo que quieres es que a partir de alguna implementación de tu Dao se construya el reporte, ya es otro cuento, porque entonces al reporte que construyas tienes que darle de alta tu clase como DataSource.
La idea de iReports, es que en el designer crees el front del reporte, y ahí mismo hagas la consulta SQL, lo que te da como resultado dos ficheros, un .jasper (el "compilado"), y un .jrxml(un fichero fuente); en Java lo que harías sería una clase de utilería que invocaría a cada reporte (el .jasper) según lo necesites.

Imagen de edgar.martinez

DAO

Hola, te ayudaria pensar en DAO como un patrón que si lo aplicas en tu sistema, cuando tengas que cambiar de fuente no vas a tener que cambiar tu código.

-¿Como encajaría la consulta SQL en el diseño del sistema?
La consulta SQL encajaría como una implementación de tu DAO,
- ¿Se tendría que crear una clase para cada reporte o poner todos los reportes dentro de una sola clase?
Puedes usar el reporte reporteVentasClientes() dentro de cliento DAO, o si es un reporte que no solo esta relacionado con el cliente puedes hacer otra clase mas generica
- ¿Es recomendable que los datos se recuperen en forma de una matriz de Objetcs?
' Puedes usar classes mas sofisticadas como Mapas, o Listas,
- ¿Como es que se adaptaría este enfoque de usar consultas SQL con el patrón de diseño DAO?
La consulta SQL encajaría como una implementación de tu DAO, Otras implementaciones serian por ejemplo accesar a archivos en vez de BD, u otras fuentes.

Aqui unos buenos comentarios sobre DAO: http://www.adam-bien.com/roller/abien/entry/generic_crud_service_aka_dao , pero hay mucho mas material alla afuera,

Saludos

Imagen de julop1992

DAO Personalizado

Buena noche.

A nivel profesional, se podria crear un DAO personalizado ? El enfoque del DAO como lo he entendido es que representan las consultas que se realizan sobre el VO, pero si necesito mostrar informacion en pantalla que esta contenida en diferentes tablas, tendria que crear un VO con esos datos especificos (Dos tablas) y su respectivo DAO ?

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">