Oracle及PostgreSQL递归查询


相信大家经常会遇到这样的需求,通过一位职员的id/name获取其下属(包括非直属)所有员工列表,用java实现这个功能相信也得花上一会功夫,但是如果是依赖数据库来实现这个功能那就so easy了。先来看看Postgresql如何实现这样的功能。

  1. WITH RECURSIVE r AS (SELECT * FROM t_account WHEREname = #{accountName}
  2. unionALL
  3. SELECT t_account.* FROM t_account, r WHERE t_account.parent = r.name
  4. )
  5. SELECT * FROM r ORDERBYname

这样是不是在代码量上减轻了很多啊,具体见postgresql官方文档http://www.postgresql.org/docs/8.4/static/queries-with.html
接着来看看Oracle如何做递归查询:

从ROOT往末端遍历:

select * from t_account t start with t.parent is null connect by prior t.name=t.parent 

从末端到ROOT端遍历:select * from t_account t start with t.name='**' connect by t.parent=t.name

具体用法细节请参考oracle文档

下面再参照java的实现:

  1. publicclass JsonTreeGenerate<T extends AbstractTreeNode> {
  2. private Logger logger = Logger.getLogger(JsonTreeGenerate.class);
  3. private Lock lock = new ReentrantLock();
  4. private Set<T> set = new HashSet<T>();
  5. public Set<T> getAllChild(Set<T> sets,T node){
  6. lock.lock();
  7. try {
  8. if(set.size()>0){
  9. set.clear();
  10. }
  11. recursionFn(sets,node);
  12. } catch (Exception e) {
  13. logger.error("", e);
  14. }finally{
  15. lock.unlock();
  16. }
  17. return set;
  18. }
  19. publicvoid recursionFn(Set<T> sets , T node){
  20. set.add(node);
  21. if(hasChild(sets,node)){
  22. List<T> hashSet = getChildList(sets , node);
  23. Iterator<T> it = hashSet.iterator();
  24. while(it.hasNext()){
  25. T n = (T)it.next();
  26. if(null==node.getChildren()){
  27. node.setChildren(new ArrayList<AbstractTreeNode>());
  28. }
  29. node.getChildren().add(n);
  30. recursionFn(sets,n);
  31. }
  32. //recursionFn(accountSet,node);
  33. }
  34. }
  35. public List<T> getChildList(Set<T> list, T t){
  36. List<T> nodeList=new ArrayList<T>();
  37. Iterator<T> it = list.iterator();
  38. while(it.hasNext()){
  39. T accounts = it.next();
  40. if(accounts.getParent()==t.getId()){
  41. nodeList.add(accounts);
  42. //t.getChildren().add(accounts);
  43. }
  44. }
  45. return nodeList;
  46. }
  47. publicboolean hasChild(Set<T> list,T node){
  48. List<T> l =getChildList(list,node);
  49. if(null!=l&&l.size()>0){
  50. returntrue;
  51. }
  52. returnfalse;
  53. }
  54. }

这个一比较就知道前者处理该问题的简洁性了吧。

相关内容