先解决我自己的问题吧,原理其实很简单,关键是在实际项目开发中如何适应工期的要求。原来的实现是这样的:
//所有DAO都必须实现这个接口,在其中加工原始查询参数,并利用 //SQLBuilder创建SQL Statement,执行,然后返回用QueryResult封装 //的结果,结果可以是ValueObject(s)也可以是RowSet public interface DAOObject{ /** 执行批量查询 QueryParams params 包含查询参数和分页数据 SQLBuiler sqlBuilder SQLBuiler接口的事例――如何创建SQL */ QueryResult query(QueryParams params,SQLBuiler sqlBuilder); } //客户端这样调用 QueryFactory factory = QueryFactory.newInstance("myquery"); //准备参数... //执行查询 QueryResult qr = factory.getQuery().query(params,mySQLBuilder);
|
特别简陋的实现,但是当时没有时间做更好的。现在我们在不改变那40多个DAO模块的前提下加入对QueryResult的缓存。
public class CachedDAOQuery implements DAOQuery{ protected DAOQuery realQuery; public CachedDAOQuery QueryResult query(QueryParams params,SQLBuiler sqlBuilder){ Key key = KeyMaker.makeKey(params);//利用params生成Key //以下是伪代码 Cache cache = CacheProviderFactory.createCacheProvider().getCache(); if(cache contains key){ return cache.get(key); } else{ QueryResult qr = realQuery.query(params,SQLBuilder); cache.set(qr); return qr; } } } //工厂类也需要修改,它必须保证所有对实际DAOQuery的调用都必须经过 CachedDAOQuery这一关,代码略。
|
好了,上面用最简单的代理模式解决了我的问题,需要注意的是Cache的选择,不能用简单的Map,必须使用OSCache等产品。
这样重构就完成了。我现在不确定将RowSet缓存起来是否可行,幸好我们多数程序员采用的都是ValueObject(s)。然后就是回归测试和性能测试,如果没有问题,我们就形成一个little release发布。
下一步重构是将所有的DAO(pojo)和业务模块结合在一起,形成完整的Facade层。这篇文章提供了不错的思路:
通用查询对象最优经验
再下一步的重构...,我需要一个NB的TagLib,不但能够动态显示QueryResult的内容,而且可以在客户端排序,就像windows的ListView控件,这需要javascript的帮助,更好的情况是,不但能够显示,而且可以编辑(满足批量修改和删除的需要)。
至于整个项目的重构我会参考banq的框架,现在对EJB提供支持的框架太少了,都是POJO!