package mybatis;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
class A{
String aid;
List<B> bs=new ArrayList<B>();
List<C> cs=new ArrayList<C>();
@Override
public String toString() {
return "A [aid=" + aid + ", bs=" + bs + ", cs=" + cs + "]";
}
}
class B{
String bid;
List<C> cs=new ArrayList<C>();
@Override
public String toString() {
return "B [bid=" + bid + ", cs=" + cs + "]";
}
}
class C{
String cid;
@Override
public String toString() {
return "C [cid=" + cid + "]";
}
}
class Node{
String id;
List<Node> nodes=new ArrayList<Node>();
}
class ResultMapping{
String name;
ResultMap resultMap;
public ResultMapping(String name) {
super();
this.name = name;
}
public ResultMapping(ResultMap resultMape) {
super();
this.resultMap= resultMap;
}
public ResultMapping(String name, ResultMap resultMap) {
super();
this.name = name;
this.resultMap = resultMap;
}
public ResultMapping(){
}
}
class ResultMap{
Class clazz;
List<ResultMapping> resultMappings=new ArrayList<ResultMapping>();
public ResultMap(Class clazz) {
super();
this.clazz = clazz;
}
}
public class Main {
static Map<String,Object> cache=new HashMap<String, Object>();
static String[] cols={"aid","bid","cid"};
//模拟查出来的数据 select * from A left join B left join C
static String[][] resultSetRow={
{"a1" ,"b1" ,"c1"},
{"a2" ,"b2" ,"c5"},
{"a2" ,"b3" ,"c6"},
{"a1" ,"b1" ,"c2"},
{"a2" ,"b1" ,"c3"},
{"a2" ,"b1" ,"c4"},
{"a1" ,"b2" ,"c7"},
};
//为了简单模拟,没有递归遍历ResultMapping,只是简单的控制了递归深度
static int MAXN=2;
static List<Map<String,Object>> createResultSets(){
List<Map<String,Object>> list=new ArrayList<Map<String,Object>>();
for(int i=0;i<resultSetRow.length;++i){
Map<String,Object> res=new HashMap<String, Object>();
for(int j=0;j<cols.length;++j){
res.put(cols[j], resultSetRow[i][j]);
}
list.add( res);
}
return list;
}
static Object getRowValue(Map<String,Object> resultSet,String combinedKey,Object partialObject,ResultMap resultMap) throws Exception{
Object rowValue=partialObject;
if(rowValue==null){
rowValue=resultMap.clazz.newInstance();
for(ResultMapping mapping:resultMap.resultMappings){
if(mapping.resultMap==null){
Field field= resultMap.clazz.getDeclaredField(mapping.name);
field.setAccessible(true);
field.set(rowValue, resultSet.get(mapping.name));
}
}
// cache.put(combinedKey, rowValue);
}
for(ResultMapping mapping:resultMap.resultMappings){
if(mapping.resultMap!=null){
String cacheKey=combinedKey+resultSet.get(getKey(mapping.resultMap));
Object cacheNode=cache.get(cacheKey);
Object nest=getRowValue(resultSet, cacheKey, cacheNode, mapping.resultMap);
if(cacheNode==null){
Field field= resultMap.clazz.getDeclaredField(mapping.name);
field.setAccessible(true);
System.out.println(mapping.name+" " +rowValue.toString());
((Collection)field.get(rowValue)).add(nest);
cache.put(cacheKey, nest);
}
}
}
return rowValue;
}
static String getKey(ResultMap resultMap){
for(ResultMapping mapping:resultMap.resultMappings){
if(mapping.name!=null){
return mapping.name;
}
}
return null;
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
ResultMap cr=new ResultMap(C.class);
cr.resultMappings.add(new ResultMapping("cid"));
ResultMap br=new ResultMap(B.class);
br.resultMappings.add(new ResultMapping("bid"));
// br.resultMappings.add(new ResultMapping("cs",cr));
ResultMap ar=new ResultMap(A.class);
ar.resultMappings.add(new ResultMapping("aid"));
ar.resultMappings.add(new ResultMapping("bs",br));
ar.resultMappings.add(new ResultMapping("cs",cr));
List<Map<String,Object>> resultSetList=createResultSets();
List<A> list=new ArrayList<A>();
for(int i=0;i<resultSetList.size();++i){
String key=(String) resultSetList.get(i).get(getKey(ar));
Object partialObject= cache.get(key);
Object rowValue=getRowValue(resultSetList.get(i), key, partialObject, ar);
if(partialObject==null){
cache.put(key, rowValue);
list.add((A) rowValue);
}
}
System.out.println(list);
// for(int i=0;i<list.size();++i){
// printNode(list.get(i), 0);
// }
}
static void printNode(Node node,int n){
for(int i=0;i<=n;++i){
System.out.print("---");
}
System.out.println(node.id);
for(Node child:node.nodes){
printNode(child, n+1);
}
}
}