论坛首页 Java企业应用论坛

一次关于简化DAO设计的初步思考!

浏览 40563 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-10-12  
firebody 写道
potian 写道
DAO层还可以封装很多东西,不是简单的一个数据存取,譬如我们希望做自己的缓存,一个简单的例子例如我有一个分类树,/level1/level2/level3/,下面还可以有页面(页面可以是多级的)page1.page2.page3,在Web层可以输入
/level1/level2/level3/page1.page2.page3得到这个页面的内容,现在如果要构造这个查询语句的话就非常复杂,需要动态产生,执行的效率极低,如果是一个getPage(categoryKey,pageKey)那么我就可以在中间加入一个cache,采用编程方式也好,或者用AOPcache拦截也好,得到这个page的id,然后用getPageById(id)把他取出来。

当然这一层放在Service也可以,但这个方法可能被很多service用到,我偏向于放在DAO层次。一旦涉及到DAO被多个service所用,那么你构造参数的过程将在各个不同的service里面重复,如果你要改变的话,bang!,全部都需要变化,这是典型的重复代码的例子。

page2 page3?
这些是属于page的咚咚把。dao可以封装这么一个查询dao.getPageByName(id) (..)


我的wiki是一个可以多级分类的系统,每个分类里面都可以有多级的页面,上面的情况下page1是page2的父页面,page2是page3的父页面,所以/level1/level2/level3/page1.page2.page3指的是level1分类下面的level2子分类的level3子分类下面的page1页面的page2子页面的page3子页面,你可以直接输入url,http://xxx/pages/level1/level2/level3/page1.page2.page3存取这个页面
所以ByName是不够的,必须是一个全路径,而这个page2是可能移到page11下面的,所以这个全路径是不能够写在数据库里面的,必须是动态组装出来的。不然的话,一移动,所有下面的子节点就麻烦了,当然首先取page的时候就需要一个分类的名字和一个页面的名字,而这个分类的名字同样也是多级的,是不能写在数据库里面的。
0 请登录后投票
   发表时间:2004-10-12  
引用
我的wiki是一个可以多级分类的系统,每个分类里面都可以有多级的页面,上面的情况下page1是page2的父页面,page2是page3的父页面,所以/level1/level2/level3/page1.page2.page3指的是level1分类下面的level2子分类的level3子分类下面的page1页面的page2子页面的page3子页面,你可以直接输入url,http://xxx/pages/level1/level2/level3/page1.page2.page3存取这个页面

对于这个查找page1.page2.page3
如果因为page名字可重复带来的查询问题,那么构造一个绝对的page名目录还是可以解决问题。比如:
public class page{
 private String name;
 public String getAbsoluteTreeName();{
   StringBuffer buf=new StringBuffer();;
   buf.append(name);;
    Page parentP=this.getParentPage();;
   while(parentP!=null);{
     buf.append( "."+parentP.getName(););;
    parentP=parentP.getParentPage();;   
   }
}


}
0 请登录后投票
   发表时间:2004-10-12  
这个本来就是这样的,那是已经得到了这个page的时候。

但你去取一个页面的时候
getPage("/level1/level2/level3","page1.page2.page3")
是不是需要构造出一个动态查询语句?因为层次是不知道的,这个语句要几次自我join,效率非常低的,不用cache不足以平民愤,呵呵
0 请登录后投票
   发表时间:2004-10-12  
potian 写道
这个本来就是这样的,那是已经得到了这个page的时候。

但你去取一个页面的时候
getPage("/level1/level2/level3","page1.page2.page3")
是不是需要构造出一个动态查询语句?因为层次是不知道的,这个语句要几次自我join,效率非常低的,不用cache不足以平民愤,呵呵

我还是不理解为什么一定要用cache!
比如:
public Level getLevelByAbsolutePath(String abPath);{
List levels=this.findAllLevels();;
for(Iterator it=list.Iterator();;it.hasNext();;);{
  Level curL=it.next();;
  if(curL.getAbsolutePath.equals(abPath););
      return curL;

}
}

public Page getPageByAbsolutePath(String absoluteLevelPath,String abP);{
Level level=this.getLevelByAbsolutePath(absoluteLevelPath);;  
//...... the same logic above
}

}


}
0 请登录后投票
   发表时间:2004-10-12  
如果我的分类有3层,每一层里面有n个子分类,我的页面有n层,每一个父页面里面有n个子页面,你想想看,多少个lazy collection要被你引用到?要做多少次数据库操作?要加载多少数据?恐怖!


哦,我看错了,你没有用递归,findALl,那你的比较次数太多了,要多少次比较?照样恐怖
0 请登录后投票
   发表时间:2004-10-12  
potian 写道
如果我的分类有3层,每一层里面有n个子分类,我的页面有n层,每一个父页面里面有n个子页面,你想想看,多少个lazy collection要被你引用到?要做多少次数据库操作?要加载多少数据?恐怖!

赫赫,确实如此。很恐怖。性能杀手。
如果你的页面名字不允许更改的话,可以考虑用一个表将absolutepath与pageId对应起来。
0 请登录后投票
   发表时间:2004-10-12  
改名字、移动目录层次等等都是大问题
这个就是cache的责任了
0 请登录后投票
   发表时间:2004-10-12  
potian 写道
改名字、移动目录层次等等都是大问题
这个就是cache的责任了

如果硬是要将这个多级目录查询一个重要业务逻辑加以考虑,还是可以再重新设计一下增/该目录 增改页面的逻辑。
将这些更新与absolutepath pageId 对应表同步。
用cache,不知道您是怎么实现的?
0 请登录后投票
   发表时间:2004-10-12  
这个问题其实是个在很多系统里面出现的问题,至少我已经碰到过好几个了,例如你们整个银行的组织机构

cache实现很简单

getPage(absoluteCategoryKey,absolutepageKey)

的时候首先用categoryKey+absolutepageKey去取cache里面的id,如果找到,用这个id去取Page对象,比较一下它的absoluteCategoryKey和absolutepageKey是不是一样,如果一样的话,就表明没有过期,如果过期的话,就把从缓存去掉

如果过期或者没有找到,就直接构造一个动态查询语句把它查出来,用它的
absoluteCategoryKey和absolutepageKey放入id即可
0 请登录后投票
   发表时间:2004-10-12  
相比我出的馊主意,好的多了。
不用改原有的大部分逻辑,直接增加一个cache的访问逻辑。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics