冷雨在线
EasyJWEB,JavaScript,Spring,JPA,MySql
半路出家,现在混JAVA.
我的首页
文章
相册
圈子
留言
管理
 
    当前所在页面:首页>>文章>>EasyJWEB中优秀的查询方式
EasyJWEB中优秀的查询方式
    作者:小雨 来源: 发表时间:2008-01-04

 
 

        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();"/>        
          
<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的属性名称,如果要根据客户的电邮进行查询,可样我们改写成这样: