|
Para realizar un enlace en memoria entre dos tablas de manera que cada Maestro contenga una lista de sus detalles se ha creado el siguiente codigo de ejemplo (adjunto!!).
En pruebas este codigo utiliza:
- 141 ms en preparacion (crear dos vectores y ordenarlos) de 2000 masters con 3 detalles cada uno.
- 30 ms en tiempo de union generando un vector de detalles para cada master.
La idea es NUNCA hacer un Query SQL para traer los maestros y
luego otro query SQL por cada maestro, que traiga los detalles.
Uso de la clase
Para enlazar un vector de datos maestros con un vector de datos detalla, ambos ordenados por la llave que los une:
// Generar un joiner. Cada joiner debe saber como enlazar un maestro con sus
// detalles y como comparar para saber si un detalle es de un maestro.
Joiner joiner = new Joiner(){
void link (Object master, Object details) {
((Master)master).setDetails((Vector) details);
}
public int compare(Object o1, Object o2){
return ((Master)o1).id - ((Detail)o2).masterId;
}
};
// Enlazar
joiner.join( masters, details );
Clase de enlace
Esta clase representa la logica para realizar un enlace.
/// Clase para representar enlaces.
static abstract class Joiner {
/// Debe comparar la llave que une a master con detail
abstract int compare(Object master, Object detail);
/// Enlaza los detalles con su maestro
abstract void link(Object master, Object collection);
/// Crea una coleccion para almacenar los detalles
Object createCollection(){return new Vector();}
/// Acgrega un valor a una coleccion
void addToCollection(Object collection, Object detail){
((Vector)collection).add(detail);
}
// Enlaza valores de dos Vectores. supone que ambos estan ordenados por su link.
void join(List masters, List details){
int idxD=0;
int dSize = details.size();
for(int idxM=0; idxM<masters.size(); idxM++) {
Object master = masters.get(idxM);
Object detail=details.get(idxD);
while ( (compare(master, detail) ) < 0) idxD++;
Object collection = createCollection();
while( compare(master, detail ) == 0) {
addToCollection(collection, detail);
idxD++;
if (idxD>=dSize) break;
detail=details.get(idxD);
}
link(master,collection);
}
}
}
Notas
En el envio anterior, la clase enviada tenia varias consideraciones no discutidas...
- cada master debe tener al menos 1 detail.
- No puede haber un detail sin un master.
|