El segundo método que quiero analizar es cuando se hace uso de Beans no mapeados. Qué es esto?
Pues se trata de realizar el mapeo directo (sin métodos de asignación intermedia) de consultas hql hacia objetos de clases que no tienen su correspondiente mapping.
En el ejemplo del post anterior teniamos una tabla llamada DATA_DEMAND y su respectiva clase DataDemand (claro sin olvidarnos de su HBM respectivo). También la usaremos para este ejemplo y en los siguientes.
Asumiendo que DataDemand sea una clase que tiene varios atributos de objetos de otros tipos de clases tambien mapeadas, es decir muchas relaciones many-to-one en su HBM...
[sourcecode language='xml']
...
...
[/sourcecode]
Quizás al momento de cargar una lista, el query se ejecute rápidamente. Pero...si las relaciones many-to-one están mapeadas con
fetch="select" o fetch="join" pueden pasar dos cosas:- Tenemos el fetch sin lazy, es decir, tal como se muestra en el ejemplo...aqui si solo accedemos a atributos property (como stDataDemand) no tendriamos problemas. Pero si accedemos a los mapeados como many-to-one (como región), entonces para cada objeto de la lista se realizará un select en tiempo de ejecución para acceder al objeto. Es decir, si la lista de objetos contiene 10 elementos, realizará 10 consultas a base de datos por cada región se acceda. Y si fueran 50? O 200? ^^ Lo mismo ocurre si usamos fetch="join".
- Ahhhhh pues ahora no...lo mapeamos con fetch="select" lazy="false" ^^. Jeje...seguimos analizando y vemos que ahora en vez de realizar el query al momento que accedemos al región ya no realizará el query...porque lo ejecuto al momento de realizar la consulta y trajo ya el objeto región lleno. Pero tenemos otro problema...todos los objetos vienen ya cargados y esto hace demasiado pesada a la lista...Y solo quiero la descripción de región T_T...Emmmm en el caso que hagamos fetch="join" lazy="false" seria lo mismo pero ejecutaria todo en una sola consulta...lógicamente xD.
Entonces...el problema radica en que no requiero todo un objeto (o más objetos) completo...solo requiero una descripción (o solo resultados puntuales)...en mi caso seria un uso incesario de espacio.
Qué hacer?
En mis tantas consultas a mis partners y a la web...halle una solución algo simpatica. Y ahora la comparto con ustedes.
Planteando que es lo que requiero exactamente: un objeto pequeño para mostrar tan solo una serie de descripciones en alguna página...no quiero que me traiga nada más que la descripcion del objeto y la de algunos de los objetos que tiene internamente.
Con HQL directo hariamos?
[sourcecode language='java'] ...
query.append(" select deDataDemand, region.deRegion, kpi.deKpi ");
query.append(" from DataDemand ");
query.append(" where stDataDemand = 'A'");
...[/sourcecode]
De veras asi lo solucionamos? O_o! No lo creo...creo que seria...
[sourcecode language='java'] ...
query.append(" from DataDemand ");
query.append(" where stDataDemand = 'A'");
...[/sourcecode]
Waaaaa...ahora levantamos todos? No, no es necesario toooooooodo . La solución bien podria ser la siguiente (al fin llegue al objetivo del post u_u)...
Definimos un bean con los atributos que requerimos y atención especial al constructor...puede tener otros contructores pero es importante tener uno al menos que inicialice todos los atributos que requerimos:
[sourcecode language='java'] public class BeanDataDemand {
private String deDataDemand;
private String deRegion;
private String deKpi;
public BeanDataDemand(String deDataDemand, String deRegion, String deKpi)
{
this.deDataDemand = deDataDemand;
this.deRegion = deRegion;
this.deKpi = deKpi;
}
...
}
[/sourcecode]
Ahora planteamos el query que mapeará directamente (sin requerir HBM) los resultados de nuestro query hacia nuestro BeanDataDemand:
[sourcecode language='java'] query.append("select new ").append(BeanDataDemand.class.getName());
query.append(" (deDataDemand, region.deRegion, kpi.deKpi) ");
query.append(" from DataDemand ");
query.append(" where stDataDemand = 'A'");
List list = getHibernateTemplate().find(query.toString());
[/sourcecode]
Y ya! La lista list esta conformada por beans del tipo BeanDataDemand y puede ser usada como lo necesitemos. De esta manera podemos usar objetos más pequeños cuando la ocasión lo amerite.
Y bueno desviandome un poco del tema, HQL me refiero...tambien se podria hacer esto mismo con un query...
[sourcecode language='java'] sql.append(" SELECT DD.DE_DATA_DEMAND as \"deDataDemand\", ");
sql.append(" R.DE_REGION as \"deRegion\", ");
sql.append(" K.DE_KPI as \"deKpi\" ");
sql.append(" FROM ");
sql.append(" DATA_DEMAND DD, ");
sql.append(" REGION R, ");
sql.append(" KPI K ");
sql.append(" WHERE ");
sql.append(" DD.CO_REGION = R.CO_REGION ");
sql.append(" AND DD.CO_KPI = K.CO_KPI ");
sql.append(" AND DD.ST_DATA_DEMAND = 'A' ");
return findListOfBeans(sql.toString(), null, BeanDataDemand.class); [/sourcecode]
Todo depende de que se requiera hacer con el resultado que nos arrojará el query. En mi caso yo requeria hacer más ligera la lista de objetos que traia para solo mostrar un listado en una tabla para describir los objetos lo más posible.
En otros casos donde se podrian usar estos tipos de beans son donde se realizan operacion tal como SUM(DD.VALUE) y asi por el estilo...como decia en el párrafo anterior...todo depende de lo que se requiera.
En el siguiente post creo que ya veré el tema de criteria...ojalá sea pronto =D...saludos.
Ante todo saludos.
ResponderEliminarPor favor podrías indicarme como implemento el método: "findListOfBeans" o en qué librería lo encuentro.
Me parece bastante útil.
Gracias.
Hola, que tal, Mateo?
ResponderEliminarBueno para implementar ese método podrias usar el metodo query de la clase QueryRunner de dbutils de Apache.
Saludos =)
Gracias por la aportación..
ResponderEliminarTeneis idea si la técnica funciona en c#?
????? ???? ????????????. ? ??????????? ??????.
ResponderEliminar???????, ?????? ????? ?? ????????? ??? ?????????? ? ???? ???? ??????????...
ResponderEliminar? ?? ?????? ????? ??????? ?????????
ResponderEliminar???-?? ? ??? ????? ?????...
ResponderEliminar?? ??, ???????? ???? :). ??? ???????, ?????? ??????? ??????? ????????????? ? ?.?. ???? ?? ???????? ??????????? ?? ??????????... :( ???????? ???? ? ???, ??? ???? ???????????
ResponderEliminar??????? ?? ??????.. ????????? ??? ??????.. ????? ???? ??? ??????????.
ResponderEliminarCasino 1250678292...
ResponderEliminarCasino 1250678292...
???????? ????!
ResponderEliminar???? ?????? ?????????????, ???????????? ???????!
ResponderEliminar?? ????? ? ??? ????, ?? ? ???? ???? 2 ???????? ???????????. ((( ? ???? ???????????! :)
ResponderEliminar???????? ????, ?? ????? ???????.
ResponderEliminar"?????? ??????"
ResponderEliminarGreat article. Thanks for the great resource.
ResponderEliminarcomposition daystraining memorabilia universe kandivali sheets whence waiver bargain barrage injecting monthly
ResponderEliminarCialisterni Comparemarmazone
Hola, muy buen artículo.
ResponderEliminarMe gustaría saber si en la cláusula where de hql, puedo comparar por el resultado de un método del objeto.
Para que quede claro, si Persona tiene un método que calcula la edad en base a la fecha de nacimiento y se llama getEdad() quisiera obtener las personas que tengan edad mayor a 30 (obviamente consultando por el método getEdad y no por la fecha de naciemiento).
Gracias!