最近在做的需求有一个点是,查询上下级关系,本想着用oracl的树查询,但是会莫名少很一些数据(因为此查询涉及循环,但是这种循环是被业务允许的),也没空具体研究oracle的树查询,后来用java递归的方式,递归查询数据库,勉强实现了该需求,但是还有一些循环引用的关系没有正确展示出来,目前程序的能力,在不加业务规则的前提,因该不能完美实现此需求
代码也没优化,先贴上来,以备后用,用这个查询,比oracl树查询会多一些正确的数据
/**
* 将递归查询的从上到下的每条记录都放在一个list里
* @param treeList 记录所有查询结果,并且以对象传递的身份,传会给调用者使用
* @param aList 临时的list,记录所有被查询的id,避免循环查询同一个id
* @param conn 数据库连接
* @param projName 最开始需要查询的id
* @throws Exception
*/
public void diguiQueryDB(List<List<String>> treeList, List<String> aList, Connection conn, String projName)
throws Exception{
//记录已经查询过的id
aList.add(projName);
//拼接sql
Statement stmt = null;
ResultSet rst = null;
StringBuffer sql = new StringBuffer();
sql.append("select id,refId ");
sql.append("from testTable ");
sql.append("where id = '");
sql.append(projName);
sql.append("'");
try {
stmt = conn.createStatement();
rst = stmt.executeQuery(sql.toString());
while(rst.next()){
String id = rst.getString("id");
//如果id被查到过,就被认为是循环调用,不在向下递归
if(aList.contains(id)) {
for(List<String> childList : treeList) {
//下面的if一定会进去,因为此id已经在了
if (childList.get(childList.size() - 1).equals(projName)) {
if(!childList.contains(id)) {
List<String> tempList = new ArrayList<String>();
tempList.addAll(childList);
tempList.add(id);
treeList.add(tempList);
}
break;
}
}
continue;
} else {
aList.add(id);
}
//将查询的数据记录到总list,然后继续向下递归
for(List<String> childList : treeList) {
if(childList.get(childList.size() - 1).equals(projName)) {
if(!childList.contains(id)) {
List<String> tempList = new ArrayList<String>();
tempList.addAll(childList);
tempList.add(id);
treeList.add(tempList);
}
break;
}
}
//继续递归
diguiQueryDB(treeList, aList, conn, id);
}
} catch (Exception e) {
// TODO: handle exception
} finally {
try {
if (rst != null) {
rst.close();
}
if (stmt != null) {
stmt.close();
}
} catch (Exception e2) {
// TODO: handle exception
}
}
}