Bueno empezaré esto comentando algunas de las soluciones que he ido implementando con respecto a formas de consultar a la base de datos usando como framework de persistencia a Hibernate, compañero (para este ejemplo) de nuestro querido amigo Spring.
La mayoria de esta soluciones han sido planteadas sobretodo para mejorar la perfomance de los querys y...buscando que el usuario deje de susurrarnos al oido "más rápido"...en el buen sentido de la palabra claro está xD.
Para empezar haré algunas comparaciones entre algunos tipos de consultas que devuelvan los mismos resultados y analizaré la performance de cada uno de ellos.
Como bien dice el título primero iré a por el modo HQL, el más simple y el más directo que se puede hacer con Hibernate.
A ver...tenemos una tabla llamada DATA_DEMAND y su respectiva clase DataDemand (cualquier parecido con algun nombre de BSC...no es pura coincidencia =P)...y además un posible query dinámico (con filtros) sería:
[sourcecode language='java']
StringBuffer query = new StringBuffer();
query.append(" from DataDemand ");
query.append(" where stDataDemand = 'A'");
if(coYear != null && coYear.length() > 0)
{
query.append(" and coYear = " + coYear);
}
if(coMonth != null && coMonth.intValue() > 0)
{
query.append(" and coMonth = " + coMonth);
}
if(coRegion != null && coRegion.intValue() > 0)
{
query.append(" and region.coRegion = " + coRegion);
}
if(coKpi != null && coKpi.length() > 0)
{
query.append(" and kpi.coKpi = '" + coKpi + "' ");
}
List list = getHibernateTemplate().find(query.toString());
return list;
[/sourcecode]
Como diria Jack el destripador...ahora vamos por partes ^^...
Como vemos la primera expresión condicional que usamos es "where stDataDemand = 'A'". La mayoria de nosotros usamos el campo estado de las tablas para iniciar los querys (sobretodo cuando tenemos que armarlos dinámicamente)...esto ya que es un campo que siempre estará, que casi siempre será un parámetro por el cual se deba realizar la búsqueda. Entonces asi tendriamos más facil armar del query para usar el prefijo AND en los demás parámetros a usar.
Ahora bien, yendo un poco más alla de esta facilidad para armar querys dinámicos que nos daría usar siempre el campo estado como primer filtro...nos podriamos preguntar cuantos registros de la tabla tendrán este valor? En el caso de la mayoria de aplicaciones que he desarrollado, este campo tiene a dos valores, entonces en el mejor de los casos la mitad de los registros tenian el valor indicado 'A' (aunque en realidad el 90% de los datos tenian el campo estado con valor ACTIVO).
Esto nos lleva a deducir que el query iniciaria levantando la mitad de los registros de la tabla al aplicar el primer filtro de búsqueda...y si la tabla tuviera tan solo ...por ejemplo...1000 registros? O_O! Este tipo de práctica podria llevarnos a iniciar la selección de información con demasiados registros...como 500 registros O_o!
Entonces que hacer? Bueno alguna vez en algun curso en la universidad aprendi la lección (yo tambien hacia esto XD, recordar que en Cato la mayoria de cursos de programación se desarrollan usando JDBC XD). Analizando un poco antes de realizar los querys y con ayuda de mi DBA (y apoyo del JP estrella XD) encontramos que un análisis pequeño antes de colocar el orden en que deberian ejecutarse los filtros de búsqueda nos ayudarian a mejorar la perfomance...aunque sea al inicio de manera imperceptible ^^.
Llegada a esta conclusión...como hariamos con el problema de donde se coloca el AND pues los querys dinámicos pueden empezar con cualquiera de los N filtros que se pasen...pues la solución fue la siguiente:
[sourcecode language='java']
StringBuffer query = new StringBuffer();
query.append(" from DataDemand ");
query.append(" where 1 = 1 ");
if(coYear != null && coYear.length() > 0)
{
query.append(" and coYear = " + coYear);
}
if(coMonth != null && coMonth.intValue() > 0)
{
query.append(" and coMonth = " + coMonth);
}
if(coRegion != null && coRegion.intValue() > 0)
{
query.append(" and region.coRegion = " + coRegion);
}
if(coKpi != null && coKpi.length() > 0)
{
query.append(" and kpi.coKpi = '" + coKpi + "' ");
}
query.append(" and stDataDemand = 'A' ");
List list = getHibernateTemplate().find(query.toString());
[/sourcecode]
Usando la condicional de "1 = 1" (la cual siempre devuelve verdadero) podriamos empezar a armar tranquilamente u,u nuestros querys, ordenando los filtros del modo más conveniente y sin preocuparnos de cual de los filtros es el primero para los siguientes anteponerlos con el AND.
Entonces el query ahora podria haber mejorado en algo su perfomance. Analizándolo muy superficialmente estariamos diciendo "dame los campos que tengan este año, con este mes, de esta región y con este KPI (un campo de la tabla no se asusten XD) y que además tengan estado A (activo)", en vez de "dame los campos tengan estado ACTIVO, con el año indicado, con este mes, de esta region y con este KPI".
Bueno este pequeño truquillo serviria cuando nuestras búsquedas no deberian levantar en primera instancia todos los registros ACTIVOS de una base de datos. Y si este fuera el caso entonces el query al ejecutarse sin filtros quedaria más o menos asi "from DataDemand where 1 = 1 and stKpipDataDemand = 'A' ", lo cual nos devolveria el resultado esperado.
En el episodio 2 analizaremos otra manera de ejecutar el mismo query...quizás usando criteria o beans no mapeados...quizás...quizás...quizás... XD
no es mejor query.append(” and coMonth = ? ");
ResponderEliminaro tiene alguna ventaja hacerlo de la manera que lo planteas
[url=http://byuz7h97rl62rjfw.com/]8ic6n4dn7cht1cnf[/url]
ResponderEliminar[link=http://jb0pgmn07xzuzjo5.com/]c9n5ul20dae071q8[/link]
uv7rxtbh92nonk1u
http://zrajks5bvi2q1cgb.com/
[url=http://byuz7h97rl62rjfw.com/]8ic6n4dn7cht1cnf[/url]
ResponderEliminar[link=http://jb0pgmn07xzuzjo5.com/]c9n5ul20dae071q8[/link]
uv7rxtbh92nonk1u
http://zrajks5bvi2q1cgb.com/
[url=http://byuz7h97rl62rjfw.com/]8ic6n4dn7cht1cnf[/url]
ResponderEliminar[link=http://jb0pgmn07xzuzjo5.com/]c9n5ul20dae071q8[/link]
uv7rxtbh92nonk1u
http://zrajks5bvi2q1cgb.com/
"??????? ?? ????? ????"
ResponderEliminar? ?????? ???????...?????!
ResponderEliminar?????? ????? ??????? - ??? ????? ??? ????????? ???? ? ????. - ?. ?????????
ResponderEliminar?? ????????? ????? ???????????,
ResponderEliminar??? ??? ???????) ?????? ?????)
ResponderEliminar???)) ??? ?????))
ResponderEliminar??????o
ResponderEliminar"????????????? ?????"
ResponderEliminar"????? ?????????????. ???????."
ResponderEliminar[url=http://87k7c2p7evh42fax.com/]28a8ufg07v7vlx2p[/url]
ResponderEliminar[link=http://0ygfq4j2xas3ynnk.com/]z8b4t97b3t2o6qsz[/link]
oe5v7dvxc4q6jdnd
http://162r7kxrwlk8p99i.com/