经一同行朋友介绍,目前正在学习由国内某开源团队开源的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();"/>
<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"/>
<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>
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;
}
}
public void doQuickSearchList(WebForm form) ...{
this.doList(form);
}
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;
}
}
if (!"".equals(customerTel)) ...{
this.addQuery("obj.tel", customerTel + "%", "like");
}
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);
<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 </td>
<td height="25">$!info.sn </td>
<td height="25">$!info.title </td>
<td height="25">$!info.tel </td>
<td height="25">$!info.address </td>
<td height="25">$!info.balanceBarrel </td>
<td height="25">$!info.machine </td>
<td height="25">$!info.presentWater.intValue() </td>
<td height="25">$!info.presentTicket.intValue() </td>
<td width="12%" height="25"><input type='button' onClick="F.doEdit($!info.id)" value='编辑' class='button'>
<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从前台到后台一体的查询结构图:

发表于 @ 2008年01月04日 11:13:00 | 评论( loading... ) | 举报| 收藏