`
bubble
  • 浏览: 146001 次
  • 性别: Icon_minigender_1
  • 来自: 辽宁
社区版块
存档分类
最新评论

分析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的标签,这里有个缺陷就是页面上按钮使用的js跳转,所以大家可以看到用我提供的模板生成的jsp文件需要使用js,css和images三个文件夹中的文件。

     在WEB-INF\templete下存放的是xml和xsl模板,zooma会先将mapping文件里的信息保存在xml\bean.xml中,然后使用它和xsl文件夹下的模板进行文件生成,一次前台页面的生成样式是完全可以自己定义的,只要按照bean.xml中的数据进行编写就可以了,当然名字还是要叫那个名字。

     zooma的缺陷:

    在项目中我是这样使用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支持
12
5
分享到:
评论
7 楼 bubble 2008-11-06  
gmingsoft04 写道

请问这个系统一对多,多对一,多对多的关系在这个框架中有没有实现?
今天花了将近一天的时间把ruby on rails 配置成功了,并利用了RadRails 这个IDE
自动生成了一个简单的web系统,真个系统几乎没写代码.只该了数据库配置信息和在输入框中输入表名,以及字段就可以了.这个系统具有增删改查功能. 建议楼主可以借鉴一下ROR的思想.RUBY 有这样的简洁的系统,java应该也有的,希望更多的人参与ZOOMA开源系统.光靠作者一个人肯定是没那么多精力的,况且作者好象也是刚刚毕业不久的应届生,经验上肯定不足,希望中国JAVA届的大牛们团结起来,建立自己的开源基地.

恩,是啊,一直准备毕业论文呢,马上就要答辩了,没时间做,有空多交流吧,呵呵。
6 楼 bubble 2008-11-06  
javagun 写道

最大的不好就是基于struts1.x的,response,request,都和action耦合在一起,actionForm,和action的方法耦合在一起,struts1.x的一大弊端,淘汰struts1.x吧,基于struts2.x和spring的会更好

好久了啊,现在才看到,呵呵。老早就想改成struts2的了,而且hibernate的mapping也像改用annotation,忙毕业论文没有时间做,过年前搞定它。
5 楼 gmingsoft04 2008-09-19  
请问这个系统一对多,多对一,多对多的关系在这个框架中有没有实现?
今天花了将近一天的时间把ruby on rails 配置成功了,并利用了RadRails 这个IDE
自动生成了一个简单的web系统,真个系统几乎没写代码.只该了数据库配置信息和在输入框中输入表名,以及字段就可以了.这个系统具有增删改查功能. 建议楼主可以借鉴一下ROR的思想.RUBY 有这样的简洁的系统,java应该也有的,希望更多的人参与ZOOMA开源系统.光靠作者一个人肯定是没那么多精力的,况且作者好象也是刚刚毕业不久的应届生,经验上肯定不足,希望中国JAVA届的大牛们团结起来,建立自己的开源基地.
4 楼 javagun 2008-07-08  
最大的不好就是基于struts1.x的,response,request,都和action耦合在一起,actionForm,和action的方法耦合在一起,struts1.x的一大弊端,淘汰struts1.x吧,基于struts2.x和spring的会更好
3 楼 bubble 2008-03-17  
引用
lz不是还在用Vector吧
这个呵呵,从第一个版本开始就这么写来的
对运行没有什么大碍就一直没有改
引用
不具实用性,开发者自己用用是不错
呵呵,也不能一棒子打死,我觉得应该还是有一定实用性的
2 楼 lsqlister 2008-03-10  
lz不是还在用Vector吧
1 楼 jianfeng008cn 2008-03-10  
不具实用性,开发者自己用用是不错

相关推荐

    ZOOM A3中文说明书

    ZOOM A3中文说明书ZOOM A3中文说明书

    电子、通信、计算机大类学生课程实验的心得体会

    电子、通信、计算机大类学生课程实验的心得体会 电子、通信、计算机大类的学生课程实验是工科教育中非常重要的一环,它不仅能够加深学生对理论知识的理解,还能培养学生的实践能力和创新思维。

    【营销】任务一金融产品与金融产品营销认识.docx

    【营销】任务一金融产品与金融产品营销认识.docx

    单片机课程实验-秒表实现

    1.了解LED数码管的工作原理,为秒表时钟模块的实现打下基础。 LED数码管是一种常用的数字显示器件,通过控制每个LED的亮灭来显示数字。在秒表时钟模块中,我们需要利用LED数码管的这一特性,通过单片机控制数码管的显示,从而实现时钟的功能。因此,了解LED数码管的工作原理对于实现秒表时钟模块至关重要。 2.掌握51单片机与LED数码管的接口技术,是实现秒表时钟模块的关键。 51单片机是一种常用的微控制器,可以通过接口与外部设备进行通信。在秒表时钟模块中,我们需要通过单片机与LED数码管之间的接口,控制数码管的显示。因此,掌握51单片机与LED数码管的接口技术是实现秒表时钟模块的关键。在实际操作中,我们需要根据接口协议和数据传输方式,编写相应的程序来控制数码管的显示。 3.合理利用定时器/计数器,是实现秒表时钟模块的效率保障。 在秒表时钟模块中,我们需要实现计时功能,这需要使用到定时器/计数器。定时器/计数器可以用来产生计时脉冲,从而控制秒表的计时。通过合理利用定时器/计数器,可以提高秒表时钟模块的计时精度和效率。在实际操作中,我们需要根据具体的应用场景和需求,选择合适的定时器/计数器参

    基于LSTM的SDN流量预测与负载均衡python源码+详细注释+数据.zip

    个人98分期末大作业项目,代码完整下载可用。主要针对计算机相关专业的正在做课程设计和期末大作业的学生和需要项目实战练习的学习者。包含全部项目源码、该项目可以直接使用、项目都经过严格调试,下载即用确保可以运行!

    实验室管理微信小程序设计

    实验室管理微信小程序设计

    机械设计CNC自动打孔机(sw18可编辑+工程图)非常好的设计图纸100%好用.zip

    机械设计CNC自动打孔机(sw18可编辑+工程图)非常好的设计图纸100%好用.zip

    51单片机使用蜂鸣器来播放音乐蜂鸣器播放音乐-小星星亮晶晶

    51单片机使用蜂鸣器来播放音乐蜂鸣器播放音乐-小星星亮晶晶 通过PWM信号来控制蜂鸣器,改变PWM的频率,可以改变蜂鸣器的发声音调,从而可以播.适合新手使用

    机械设计德国6层电万能蒸烤箱(sw21可编辑+cad)非常好的设计图纸100%好用.zip

    机械设计德国6层电万能蒸烤箱(sw21可编辑+cad)非常好的设计图纸100%好用.zip

    node-v12.22.5-darwin-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    超声波传感器系列 UFA-150, UFA-200 安装指南

    超声波传感器系列 UFA-150, UFA-200 安装指南

    VOS4890 户外电源系统 用户手册

    VOS4890 户外电源系统 用户手册

    金融产品可行性报告.docx

    金融产品可行性报告.docx

    node-v12.18.2-linux-s390x.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    printer.cfg

    printer.cfg

    【计算机二级实操】液晶背光开关控制实验(汇编语言).zip

    【计算机二级实操】液晶背光开关控制实验(汇编语言).zip

    Java毕业设计-基于SpringBoot + Vue 的音乐网站系统 (源码+数据库+文档).zip

    基于Spring Boot和Vue的音乐网站系统是一种使用Spring Boot框架和Vue框架进行开发的在线音乐平台系统。下面是一个简单的介绍: 后端(Spring Boot)部分: 1. 数据库设计:设计合适的数据库模式来存储音乐信息,包括歌曲、专辑、歌手等相关信息。 2. 接口设计:根据需求设计合适的RESTful API接口,用于处理前端请求。您可以使用Spring MVC来开发这些接口,并使用Spring Data JPA来处理数据库访问。 3. 用户管理:实现用户注册、登录、权限管理等功能。使用Spring Security来处理用户认证和授权。 4. 音乐资源管理:上传/编辑/删除音乐、/删除/编辑/分类专辑和歌手等功能。您可以使用Spring Boot提供的文件上传和管理功能,以及数据库来存储和管理相关信息。 5. 推荐系统:实现根据用户的兴趣和行为进行个性化的音乐推荐。可以使用协同过滤、内容推荐或机器学习等技术来进行推荐算法的实现。 前端(Vue)部分: 1. 页面设计:使用Vue框架用户界面,包括首页、歌单推荐、搜索、歌手页面等。使用Vue Router

    中国各地级市工业三废数据(2006-2021年).xlsx

    中国各地级市工业三废数据(2006-2021年).xlsx

    基于扩散模型的半监督脑肿瘤分割内含数据集和环境说明.zip

    本项目致力于基于扩散模型的半监督脑肿瘤分割,旨在提高医学影像在脑肿瘤诊断中的应用。项目利用扩散模型对脑部MRI影像中的肿瘤区域进行精确分割。 在数据集方面,我们使用了公开的脑部MRI影像数据集,如BRATS、Medical Segmentation Decathlon等,并进行了预处理,包括格式转换、裁剪、翻转等操作。在环境搭建方面,我们使用Python编程语言,基于TensorFlow和PyTorch深度学习框架进行开发。为了提高计算效率,我们还使用了GPU加速计算。此外,我们还采用了Docker容器技术,确保实验结果的可重复性。 项目完成后,将实现对脑部MRI影像中肿瘤区域的精确分割,为脑肿瘤的诊断和治疗提供有力支持。同时,项目成果也可应用于其他医学影像分析领域,如肿瘤检测、病变分割等。

    python学习导航.txt

    python烟花代码

Global site tag (gtag.js) - Google Analytics