分析zooma敏捷框架的優點和缺陷

最初想寫zooma的原因是因爲自己感到對經常性的重複勞動的厭煩,諸如一些po和vo的轉換,針對不同entity的dao和service的實現,以及基本的action中crud操作,即使對dao和service以及action做了泛型的封裝,還是要寫不少的重複代碼,前臺的頁面也是要來回的粘貼複製,於是我就有了zooma的原始模型:

就是通過hibernate的mapping文件自動的生成對entity的包括po,vo,dao,service,action,actionform和前臺的頁面,一次性生成對該實體的包括c、s兩端的基本操作代碼,當然包括spring和struts的配置文件的更新,使得我可以把大部分的精力放在對於特定實體的特定邏輯的設計上。

到zooma0.3版本,以上的模型已經全部實現,使用zooma爲基礎的山西某煤礦生產調度信息系統也同時完成收尾工作,在開發過程中遇到了zooma的先天缺陷,在後面會給大家介紹,希望使用它的人能夠避免犯同樣的錯誤。下面我來分析一下zooma的優點和缺點:

首先我對後臺的代碼做了優化,使用泛型對dao,service和action做了基本操作的封裝,這樣可以看到dao實現的代碼如下:

public class ZsxResumeDAO extends BabyDao <ZsxResume,Integer>{

}

service實現的代碼如下:
(1)oracle下的代碼

public class ZsxResumeService extends BabyService<ZsxResumeDAO,ZsxResume,ZsxResumeVO>{

}

(2)mysql下的代碼

public class ZsxResumeService extends BabyService<ZsxResumeDAO,ZsxResume,ZsxResumeVO>{

public boolean delete(String[] ids){
try {
for(int i=0;i<=ids.length;i++){
this.getDao().delete(Integer.parseInt(ids[i]));
}
return true;
} catch (Exception e) {
return false;
}
}
public ZsxResumeVO findById(String id) {
CoypUtil.copyProperties(this.getVo(),this.getDao().findById(Integer.parseInt(id)));
return this.getVo();
}

}


action實現的代碼:

public class ZsxResumeAllAction extends BabyActionAdvan<ZsxResumeService,ZsxResume,ZsxResumeVO,ZsxResumeForm>{
/**
* Struts execute
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
String action=request.getParameter("action");
String actionForward="404Failed";
if ("insert".equals(action)) {
/*insert表示插入,由xxx_add.jsp跳入,跳轉xxx_index.jsp*/
if (insert(form))actionForward="zsxResume_insert";
}else if("update".equals(action)) {
/*update表示修改,由xxx_update.jsp跳入,跳轉xxx_index.jsp*/
if(update(form))actionForward="zsxResume_update";//xxx_index.jsp
}else if("show".equals(action)) {
/*show表示修改顯示,由xxx_index.jsp或xxx_query.jsp跳入,跳轉xxx_update.jsp*/
String id=request.getParameter("id");
vo= (ZsxResumeVO)(service).findById(id);
Vector<ZsxResumeVO> v=new Vector<ZsxResumeVO>();
v.add(vo);
request.setAttribute("result",v );
actionForward="zsxResume_show";
}else if("delete".equals(action)) {
/*delete表示刪除,由xxx_index.jsp或xxx_query.jsp跳入,跳轉xxx_index.jsp或xxx_query.jsp*/
String[] ids=request.getParameterValues("id");
if (!delete(ids))actionForward="zsxResume_delete";
}else{
/*query,由xxx_index.jsp或xxx_query.jsp跳入*/
Page p=query(form, request, "zsxResume");/*第三個參數需要相應修改,值爲當前action的path名稱*/
request.setAttribute("result",p.getItems());
request.setAttribute("page",p);
/*判斷是主頁跳入,還是查詢頁跳入*/
if ("index".equals(this.form)){
//主頁跳入,應該跳回主頁
actionForward = "zsxResume_index";//xxx_index.jsp
}else if("query".equals(this.form)){
//查詢頁跳入,應該跳回查詢頁
actionForward = "zsxResume_query";//xxx_query.jsp
}
}
return mapping.findForward(actionForward);
}
/**
* overrided begin
*/

/**
* ActionForm to VO
*/
public void copyForm(ZsxResumeForm form) {
ZsxResumeForm f = form;

if(f.getId()!=null) {
if(!f.getId().equals(""))vo.setId(new Integer(f.getId()));
}

if(f.getAge()!=null) {
if(!f.getAge().equals(""))vo.setAge(new Integer(f.getAge()));
}

if(f.getSalary()!=null) {
if(!f.getSalary().equals(""))vo.setSalary(new Float(f.getSalary()));
}

if(f.getBrithday()!=null) {
if(!f.getBrithday().equals(""))vo.setBrithday(DateUtil.stringToDate(f.getBrithday()));
}

vo.setName(f.getName());

vo.setCity(f.getCity());

}
/**
* query rules
*/
public DetachedCriteria getDetachedCriteria(ZsxResume po){
//建立查詢規則
DetachedCriteria dc=DetachedCriteria.forClass(ZsxResume.class);

if(po.getName()!=null&&!po.getName().equals("")){
dc.add(Restrictions.like("name",po.getName(),MatchMode.ANYWHERE));
}

if(po.getCity()!=null&&!po.getCity().equals("")){
dc.add(Restrictions.like("city",po.getCity(),MatchMode.ANYWHERE));
}

if(po.getId()!=null&&!po.getId().equals("")){
dc.add(Restrictions.eq("id",new Integer(po.getId())));
}

if(po.getAge()!=null&&!po.getAge().equals("")){
dc.add(Restrictions.eq("age",new Integer(po.getAge())));
}

if(po.getSalary()!=null&&!po.getSalary().equals("")){
dc.add(Restrictions.eq("salary",new Float(po.getSalary())));
}

if(po.getBrithday()!=null&&!po.getBrithday().equals("")){
dc.add(Restrictions.eq("brithday",po.getBrithday()));
}

dc.addOrder(Order.desc("id"));
return dc;
}
}


這些代碼相對在量上有了明顯的壓縮,也更加的適合擴展,比如我希望在dao中添加一個按照name來查詢的方法,直接在dao裏添加如下方法就可以了:

public List findByName(String name){
return this.getHibernateTemplate().find("from ZsxResume where name=?",name);
}

再比如我想使用其它實體的操作,只要在這個實體中用geter和seter注入就可以使用,當然相應的要在spring的配置文件中加入參數信息。

在action中只實現了單獨實體的crud操作,想實現批量操作,可以自己重寫insert(),delete(),update()方法,同樣也可以通過ioc使用其他實體的crud操作
在查詢方面使用hibernate的QBC進行動態混合查詢,查詢規則在action中的getDetachedCriteria方法中定義,同時將分頁封裝了進去,可以自己修改org.zooma.base.Page類的toString()方法,來改變翻頁顯示條。

頁面中儘量將java代碼最少化,使得代碼看起來更加易懂,所以使用了struts的標籤,[b]這裏有個缺陷就是[/b]頁面上按鈕使用的js跳轉,所以大家可以看到用我提供的模板生成的jsp文件需要使用js,css和images三個文件夾中的文件。

在WEB-INF\templete下存放的是xml和xsl模板,zooma會先將mapping文件裏的信息保存在xml\bean.xml中,然後使用它和xsl文件夾下的模板進行文件生成,一次前臺頁面的生成樣式是完全可以自己定義的,只要按照bean.xml中的數據進行編寫就可以了,當然名字還是要叫那個名字。

[b]zooma的缺陷:[/b]

在項目中我是這樣使用zooma的,單表直接只用zooma生成就ok了,多表關聯的時候,先建立視圖,然後對視圖做生成——這裏對錶和視圖有一定的限制,就是一定要以id爲主鍵,並且id在oracle中使用number、在mysql中使用integer,否則會出錯誤,這個應該算是個缺陷吧——生成的視圖用來顯示關聯後的實體數據,對視圖修改的時候,卻修改要被修改的被關聯的單表,如果說對於比較簡單的邏輯關係這樣操作還是沒有問題的,但是我們在實際項目中遇到的比較複雜的邏輯,使得實現的十分複雜,所以建議對多表關聯使用zooma對單邊生成後自己修改mapping文件和po、vo,使用hibernate的many-to-many進行操作,這是zooma得最大缺陷,它只能爲開發者在比較簡單的實體邏輯(一般我會在這樣的邏輯中使用zooma:單表,many-to-one,one-to-many)下生成應用,使用它來做一些小型項目我絕得還是會很有益處的。

還有就是zooma是基於struts1.2的,這令很多網友感到失望,我在演示視頻中使用myeclipse進行項目搭建,有讓很多人感到絕望,實際上完全可以除了基本架構的搭建,其他操作完全可以不使用myeclipse,但是需要自己手動寫mapping文件和po。

在zooma的下個版本中希望實現:
1、ant的項目導入,擺脫Myeclipse
2、升級爲Struts2.0,有可能的話會添加ibates支持
發佈了17 篇原創文章 · 獲贊 0 · 訪問量 1917
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章