viernes, enero 21, 2011

Optimizar consultas con iBatis y Joins

Se me ha dado un caso en el que tenía que recuperar una lista con objetos complejos de una consulta. La consulta usaba un join con otra tabla que, además de devolver tipos simples (String) también debía completar un tipo complejo (una lista de objetos).

En concreto, necesitaba conocer las personas activas (con contrato sin finalizar) y los centros de trabajo que estos contratos tenían (1:N persona/contrato y 1:N contrato/centro). Con lo que la consulta me devolvería un registro por cada centro que el contrato tuviera asociado. Es por ello que el bean al que se mapea el resultado contiene objetos simples (Strings con los datos personales) y un objeto complejo (una lista de objetos Centro por cada persona).

Para resolver este "problema", he usado la siguiente "estrategia" (las consultas así como las relaciones entre tablas, se han simplificado para su mejor entendimiento):

<resultmap id="selectPersonasContratoActivoResult" class="persona" groupby="idContrato">
<result property="idPersona" column="ID_PERSONA">
<result property="nombre" column="NOMBRE">
<result property="idContrato" column="ID_CONTRATO">
<result property="centros" resultmap="selectCentrosContratoResult">
</result>

<resultmap id="selectCentrosContratoResult" class="centro">
<result property="idCentro" column="ID_CENTRO">
<result property="nombre" column="NOMBRE">
</result>

<select id="selectPersonasContratoActivo" resultmap="selectPersonasContratoActivoResult"> </select>

<select id="selectCentrosContrato" parameterclass="int" resultmap="selectCentrosContratoResult"> </select>

Lo importante en este código es las siguientes líneas:


<resultmap id="selectPersonasContratoActivoResult" class="persona" groupby="idContrato">

... donde indicamos cuál será la clave por la que agrupemos los resultados que se mapearán a la lista "centros", y esta otra línea


<result property="centros" column="ID_CONTRATO" resultmap="selectCentrosContratoResult">

... ya que aquí se indica que el objeto complejo (lista) "centros" se rellenará atendiendo al resultMap selectCentrosContratoResult.

De esta forma, con una sola consulta conseguimos completar un bean que contiene una lista de otro bean.

Espero haberme sabido explicar bien. Si no es así, siempre se puede consultar esta página