EasyJWEB中优秀的查询方式

         经一同行朋友介绍,目前正在学习由国内某开源团队开源的J2EE MVC框架EasyJWEB(等同于大家熟悉的struts)。EasyJWEB中提供了优秀的查询方式,是一种完全基于面向对象并支持AJAX动态的查询方式。不需要开发人员过多的去熟悉JDBC查询式的SQL语句就能随意的查询,并且提供了更大的查询弹性。
        下面我以项目中应用到EasyJWEB的一个CRUD为例,演示一下EasyJWEB是如何进行数据查询的,并且在Views层使用到了EasyJWEB提供的AJAX动态来加载查询到的数据,
首先Views层中新建一个HTML模板文件名为list.html,内容如下: 

代码:

< link  href ="/include/css.css"  rel ="stylesheet"  type ="text/css" >
< script  type ='text/javascript'  src ='/ejf/easyajax/prototype.js' ></ script >
< script  type ='text/javascript'  src ='/ejf/easyajax/engine.js' ></ script >
< script  type ='text/javascript'  src ='include/easyjweb-util.js' ></ script >
< script  type ="text/javascript" >
F
=new FORM("customer.ejf","ListForm",true);
gotoPage
=function(n){
    $(
"currentPage").value=n;
    quickSearchCustomer();
}

</ script >

< span >
  
< table  width ="100%"  height ="97%"  align ="center"  cellspacing ="0"  style ="margin-top:4px;" >
    
< tr >
      
< td  height ="20"  bgcolor ="#FFFFFF"  class ="tablehead" > 客户信息查询 </ td >
    
</ tr >
    
< tr >
      
< td  valign ="top" >< table  height ="100%"  cellspacing ="0"  style =" margin:-2px -4px -2px -4px; width:101%" >
      
< form  id ="ListForm"  name ="ListForm"   method ="post"  action ="customer.ejf" >
  
< input  type ="hidden"  name ="easyJWebCommand"  value ="quickSearchList" />
  
< input  type ="hidden"  name ="id"  value ="$!id"   />
  
< input  type ="hidden"  name ="mulitId"  value ="$!mulitId"   />
  
< input  type ="hidden"  name ="currentPage"  id ="currentPage"  value ="$!currentPage" />
  
< input  name ="orderBy"  type ="hidden"  value ="$!orderBy" />
  
< input  name ="orderType"  type ="hidden"  value ="$!orderType" />
          
< tr  class ="tablehead3" >
            
< td  height ="25" > 电话号码:
              
< input  name ="customerTel"  type ="text"  class ="form_text"  id ="customerTel"  onKeyUp ="if(this.value.length>1)quickSearchCustomer();" /></ td >
            
< td  height ="25" > 名  称:
              
< input  name ="customerTitle"  type ="text"  class ="form_text"  id ="customerTitle"  onKeyUp ="if(this.value.length>0)quickSearchCustomer();" /></ td >
          
</ tr >
          
< tr  class ="tablehead3" >
            
< td  height ="25" > 编  号:
              
< input  name ="customerSn"  type ="text"  class ="form_text"  id ="customer-sn"  onKeyUp ="if(this.value.length>1)quickSearchCustomer();" /></ td >
            
< td  height ="25" > 地  址:
              
< input  name ="customerAddress"  type ="text"  class ="form_text"  id ="customer-address"  onKeyUp ="if(this.value.length>1)quickSearchCustomer();" /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
          
< input  name ="add"  type ="button"  id ="add"  value ="添加"  onClick ="loadPage('customer.ejf?cmd=add');"  class ="button"   />
              
</ td >
          
</ tr >
          
</ form >
          
< tr  align ="center" >
            
< td  height ="20"  colspan ="2"  valign ="top"  class ="tablehead" > 查询结果  </ td >
          
</ tr >
          
< tr  align ="center" >
            
< td  colspan ="2"  valign ="top"  class ="tablehead2" >< div   id ="mainTable"  class ="tablehead3"  style ="height:100%;overflow:auto;" >   </ div ></ td >
          
</ tr >
          
< tr  align ="center" >
            
< td  height ="25"  colspan ="2"  valign ="top"  class ="tablehead" >< span  id ="pageInfo" ></ span ></ td >
          
</ tr >
        
</ table ></ td >
    
</ tr >
  
</ table >
< script >
quickSearchCustomer
=function(){
  EasyAjaxUtil.ajaxSubmit(
"ListForm","mainTable");
}
 
quickSearchCustomer();
</ script >
</ span >

        List.html页面就是用于显示查询得到的数据列表,其中重点看一下这句JS:EasyAjaxUtil.ajaxSubmit("ListForm","mainTable");EasyAjaxUtil支持通过ajax的方式提交表单的内容,其中ajaxSubmit方法就是用来实现表单以Ajax局部刷新的方式提交的功能。使用方法EasyAjaxUtil.ajaxSubmit(formName,targetId)。
来提交表单ListForm,并把表单执行的结果返回到页面上ID为mainTable中。
再来看一下这两句:

< form  id ="ListForm"  name ="ListForm"   method ="post"  action ="customer.ejf" >
< input  type ="hidden"  name ="easyJWebCommand"  value ="quickSearchList" />
        意思也就是说当页面以AJAX的方式提交表单时,会去后台查找到CustomerAction这个类并执行方法doQuickSearchList()。
注意:需要使用到EasyJWEB提供的AJAX支持的页面,都必须在页面中先引入如下JS文件:
< script  type ='text/javascript'  src ='/ejf/easyajax/prototype.js' ></ script >
< script  type ='text/javascript'  src ='/ejf/easyajax/engine.js' ></ script >
< script  type ='text/javascript'  src ='include/easyjweb-util.js' ></ script >
        现在再来看一下后台JAVA部分的代码,首先看一下CustomerAction部份的代码:
package  com.easyjf.microerp.mvc;

import  java.io.Serializable;
import  java.util.HashMap;
import  java.util.List;
import  java.util.Map;

import  com.easyjf.container.annonation.Inject;
import  com.easyjf.core.support.query.IQueryObject;
import  com.easyjf.core.support.query.QueryObject;
import  com.easyjf.microerp.domain.Customer;
import  com.easyjf.microerp.query.CustomerQueryObject;
import  com.easyjf.microerp.service.ICustomerService;
import  com.easyjf.web.Module;
import  com.easyjf.web.Page;
import  com.easyjf.web.WebForm;
import  com.easyjf.web.tools.AbstractCrudAction;
import  com.easyjf.web.tools.IPageList;

/**
 * CustomerAction
 * 
 * 
@author 冷雨
 * 
 
*/

public   class  CustomerAction  extends  AbstractCrudAction  {
    @Inject
    
private ICustomerService service;

    
public void setService(ICustomerService service) {
        
this.service = service;
    }


    
public void doQuickSearchList(WebForm form) {
        
this.doList(form);
    }


    
/*
     * to get the entity class
     
*/

    @SuppressWarnings(
"unchecked")
    
protected Class entityClass() {
        
return Customer.class;
    }


    
/*
     * to find the entity object
     
*/

    
protected Object findEntityObject(Serializable id) {
        
return service.getCustomer((Long) id);
    }


    
/*
     * to get the entity query param queryObject return IPageList
     
*/

    
protected IPageList queryEntity(IQueryObject queryObject) {
        ((QueryObject) queryObject).setPageSize(
15);
        
return service.getCustomerBy(queryObject);
    }


    
/*
     * to remove an entity param id
     
*/

    
protected void removeEntity(Serializable id) {
        service.delCustomer((Long) id);
    }


    
/*
     * to batch remove the entities param ids
     
*/

    
protected void batchRemoveEntity(List<Serializable> ids) {
        service.batchDelCustomers(ids);
    }


    
/*
     * save object to entity
     
*/

    
protected void saveEntity(Object object) {
        service.addCustomer((Customer) object);
    }


    
/*
     * update an entited object
     
*/

    
protected void updateEntity(Object object) {
        service.updateCustomer(((Customer) object).getId(), (Customer) object);
    }


    @Override
    
protected Class getQueryClass() {
        
return CustomerQueryObject.class;
    }

}
        关于EasyJWEB Action的处理、调用这方面的文章在网上以是雪花飘,如果你实是在看不懂,请留言或去他们官网BBS上去发帖求解( http://www.easyjf.com)。
这里重点说一下两个地方:
方法doQuickSearchList:
public   void  doQuickSearchList(WebForm form)  {
        
this.doList(form);
}
        看到没,很简洁的代码,完全没有业务逻辑,在这里只是起到了一个调控流程的作用。也即是去调用执行this.doList(form);请想一想为什么在前台而不直接写成去执行doList方法,而要通过去执行doQuickSearchList()再间接调用doList()方法呢?但是你可能会发现在CustomerAction类中根本找不到方法doList(),因为这个方法是在父类AbstractCrudActionk中,在父类中的doList()方法又去调用了queryEntity()这个抽象方法,这个方法是需要你在子类CustomerAction类中去实现并调用业务逻辑层的。
protected  IPageList queryEntity(IQueryObject queryObject)  {
    ((QueryObject) queryObject).setPageSize(
15);
    
return service.getCustomerBy(queryObject);
}

        查询参数queryObject里封装了用户的查询条件,在业务逻辑层中会根据指定的查询参数,查询实体。并返回一个又是封装了分页信息等的IPageList。


        2。方法getQueryClass与父类中的方法doList:
在上面说到了查询参数,那EasyJWEB是如何知道我们的查询条件的呢,比如在这里我有一个查询条件是这样的:查询电话号码以132开头,并且地址是在“重庆市”这个范围内的客户。

请重点看一下方法getQueryClass 与父类中的方法doList()

@Override
protected  Class getQueryClass()  {
    
return CustomerQueryObject.class;
}

public   void  doList(WebForm form)  {
    IPageList pageList 
= queryEntity((IQueryObject) form
                .toPo(getQueryClass()));
    CommUtil.saveIPageList2WebForm(pageList, form);
}

          如果你手中没有EasyJWEB的源代码(ftp://ftp1.easyjf.com/easyjweb/easyjweb-1.0-m3/easyjweb-1.0-m3.zip)将无法看到doList方法,不过你可以通过上面的链接去下载得到它的源代码,以便能更清楚的明白这里Action的工作方式。首先看一下doList()方法,
form.toPo(getQueryClass())将把form表单中的数据转换成getQueryClass()方法返回的类中,默认为通用查询对象QueryObject.class,由于这里我们在子类CustomerAction中重构了getQueryClass()方法。所以这里将把FORM表单中的数据转换成CustomerQueryObject.class这个类中对应的属性值。
如:在前台FORM表单中有一个input

< input name = " customerTel "  type = " text "  Value = " 13251114XXX "   />

 

         在后台查询类CustomerQueryObject.class中也有一个对应的属性customerTel,这样通过form.toPo(CustomerQueryObject.class)就能把前台name="customerTel"的值加载到该类中。当然,这里只是为了查询才建立的一个查询对象,如果是只为了得到前台某一个对象的值,采用这种方式是不可取的,而可以改用String strName = (String)form.get("name");这样得到的将是一个字符串。


3。查询核心类CustomerQueryObject.class

package  com.easyjf.microerp.query;

import  com.easyjf.core.support.query.QueryObject;

/**
 * Customer查询对象
 * 
 * 
@author 冷雨
 * 
 
*/

public   class  CustomerQueryObject  extends  QueryObject  {
    
private String customerTel = "";
    
private String customerTitle = "";
    
private String customerSn = "";
    
private String customerAddress = "";

    @Override
    
public void customizeQuery() {
        
if (!"".equals(customerTel)) {
            
this.addQuery("obj.tel", customerTel + "%""like");
        }

        
if (!"".equals(customerTitle)) {
            
this.addQuery("obj.title""%" + customerTitle + "%""like");
        }

        
if (!"".equals(customerSn)) {
            
this.addQuery("obj.sn", customerSn, "=");
        }

        
if (!"".equals(customerAddress)) {
            
this.addQuery("obj.address""%" + customerAddress + "%""like");
        }

        
super.customizeQuery();
    }


    
public void setCustomerTel(String customerTel) {
        
this.customerTel = customerTel;
    }


    
public void setCustomerTitle(String customerTitle) {
        
this.customerTitle = customerTitle;
    }


    
public void setCustomerSn(String customerSn) {
        
this.customerSn = customerSn;
    }


    
public void setCustomerAddress(String customerAddress) {
        
this.customerAddress = customerAddress;
    }


}
        仔细看一下,这个查询类继承了查询基类QueryObject,并且都实现了查询接口IQueryObject,如果在上面的Action中不重构方法getQueryClass(),则默认查询对象就是QueryObject,所以其实这里把查询对象重构为CustomerQueryObject.class,也只是为了一个目的,扩展查询基类并动态加入查询条件,那CustomerQueryObject.class类是如何动态得到查询条件的呢?注意看那几个IF语句,如:
if  ( ! "" .equals(customerTel))  {
    
this.addQuery("obj.tel", customerTel + "%""like");
}
        当前台页面name="customerTel"对象有值时,在form.toPo(CustomerQueryObject.class)后。IF语句这里也就应该有值,所以也就是当通过客户的电话号码进行查询时,向查询对象中加入一个查询条件,加入这个查询条件不用我们掌握很深的SQL语句,完全是基于面向对象的写法。注意这里的第一个参数"obj.tel",tel这就是需进行查询的属性,这个属性并不一定就是数据库中的字段,而是你项目中域对象(DoMain)Customer.java的属性名称,如果要根据客户的电邮进行查询,可样我们改写成这样:
if  ( ! "" .equals(email))  {
    
this.addQuery("obj.email", email+ "%""like");
}

注意:
一定要先在CustomerQueryObject.class对象中增加一个属性private String email = "";
if (!"".equals(email)) 这里的"email"名称一定要与上面的属性名称一致并且与前台表单中的name名称一致。
this.addQuery("obj.email", email+ "%", "like");这里的第一个email一定要与域对象中属性名称一致,第二个email也就是上面从前台得到的email值。
新增加一个查询属性,都必须有一个对应的set方法。

       最后Action层会调用业务逻辑层相应的方法进行查询,并返回包含了分页信息的IPageList,

return   this .service.getCustomerBy(queryObject);
        刚才,在前面提到,在Action中为什么要使用方法doQuickSearchList(),而不直接调用doList(),这是因为由于我们Action继承了父类AbstractCrudAction,继承了该类的Action不需要写返回模板页面,它会自动根据方法名称查找与方法名一致的模板文件,如在这里则会把查询得到的IPageList返回到模板文件quickSearchList.html中,如果我们直接使用方法doList()则会返回到list.html页面中。这样就会全部刷新list这个页面,而不是局部刷新。所以这样不能达到动态加载、局部刷新的AJAX效果。
quickSearchList.html中的代码为:
< table  width ="100%"  cellspacing ="0"  style =" margin:-2px -4px -2px -4px; width:100%"    >
  
< thead >
    
< tr  align ="center"  class ="tablehead3" >
      
< td  width ="30"  height ="25" > 序号 </ td >
      
< td  height ="25" > 客户编号 </ td >
      
< td  height ="25" > 客户名称 </ td >
      
< td  height ="25" > 电话 </ td >
      
< td  height ="25" > 地址 </ td >
      
< td  height ="25" > 欠空桶 </ td >
      
< td  height ="25" > 赠机 </ td >
      
< td  height ="25" > 赠水 </ td >
      
< td  height ="25" > 赠票 </ td >
      
< td  height ="25" > 操作 </ td >
    
</ tr >
  
</ thead >
  
< tbody  >
  
  #foreach( $info in $!list)
  
< tr  align ="center"  class ="tablehead3" >
    
< td  height ="25" > $!velocityCount &nbsp; </ td >
    
< td  height ="25" > $!info.sn &nbsp; </ td >
    
< td  height ="25" > $!info.title &nbsp; </ td >
    
< td  height ="25" > $!info.tel &nbsp; </ td >
    
< td  height ="25" > $!info.address &nbsp; </ td >
    
< td  height ="25" > $!info.balanceBarrel &nbsp; </ td >
    
< td  height ="25" > $!info.machine &nbsp; </ td >
    
< td  height ="25" > $!info.presentWater.intValue() &nbsp; </ td >
    
< td  height ="25" > $!info.presentTicket.intValue() &nbsp; </ td >
    
< td  width ="12%"  height ="25" >< input  type ='button'  onClick ="F.doEdit($!info.id)"  value ='编辑'   class ='button' >
      
&nbsp;&nbsp;
      
< input  type ='button'  onClick ="if(confirm('是否真的要删除?')){F.doDel($!info.id);}"  value ='删除'  class ='button'  ></ td >
  
</ tr >
  #end
  
</ tbody >
</ table >
< span  id ="thePageInfo"  style ="display:none;" > $!paginationDC </ span >
< script >
    $(
"pageInfo").innerHTML=$("thePageInfo").innerHTML;
    $(
"currentPage").value="$!page";              
</ script >

 以下是EasyJWEB从前台到后台一体的查询结构图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值