Da: Mark Bennett [mailto:[EMAIL PROTECTED]
Inviato: giovedì 19 maggio 2005 20.28
A: ibatis-user-java@incubator.apache.org
Oggetto: A really bad N+1 solution
/**
* Translates a List of maps into a normailzed
structure. Choose any number
* of column names and pass them in
as an array. The result will be an object
* graph grouped in the
same order as the order of the column names passed in.
* Each parent
is a map with an element called "child" that holds a List of
* Maps
which in turn have their own child list. An added feature is that the
* root holds the sum of its children on each level in a key called
*
'numChildLevels*'. Just substitute an integer for the *.
*
* This is most often used for reports. This allow you to get
all the data
* with one call and then create the structure you
need. This saves
* potentially hundreds of database calls while
recursing.
*/
public static List normalizeListOfMaps(List
dataList, String[] colHeaders){
List
focus = null;
List lastRowVals = new ArrayList(
colHeaders.length);
List childList = null;
Map
currRow = null;
Map lastRow = null;
Map rootMap
= null;
int n = 0;
String key = null;
String curr = null;
String last = null;
// The focus holds a reference to the active parent at
each level.
List[] focusLevel = new
List[colHeaders.length];
focusLevel[0] = new
ArrayList();
Iterator i =
dataList.iterator();
while (i.hasNext()) {
currRow= (Map) i.next();
for (n = 0; n < colHeaders.length; n++) {
key = (String) colHeaders[n];
curr = (String)
currRow.get(key);
if (lastRow !=
null)
last = (String)
lastRow.get(key);
if (last == null || !curr.equals(last)) {
if (n == 0) {
rootMap = currRow;
}
focus =
focusLevel[n];
focus.add(currRow);
// Keep a sum of all the levels in each root
record.
Integer sum = (Integer)
rootMap.get("numChildLevels" + (n));
if (sum !=
null)
rootMap.put("numChildLevels" + (n),
new Integer(sum.intValue() +
1));
else
rootMap.put("numChildLevels"
+ (n), new Integer(1));
// When not a leaf node.
if (n < colHeaders.length - 1)
{
childList = new ArrayList();
focusLevel[n+1] =
childList;
currRow.put("child",childList);
// Create a copy so it can have its own child pointer.
currRow = new
HashMap(currRow);
}
}
}
lastRow =
currRow;
}
return
focusLevel[0];
}