环境:Tomcat 5.0,JDK1.4 myEclipse5.1,Hibernate3.1,Oracle 8i.
创建表的脚本:
--create table.
create table COD_MAIN
(
ID NUMBER not null,
CD_STYLE NUMBER(22),
CD_CODE VARCHAR2(10),
CD_CHINA VARCHAR2(60),
CD_PY VARCHAR2(10)
)
实现效果为:根据国家区域码标准,在用户输入数字,英文或者中文的时候,自动匹配.
首先使用myEclipse生成Hibernate映射文件.<hibernate-mapping>
<class name="com.huadi.CodMain" table="COD_MAIN" >
<id name="id" type="java.lang.Long">
<column name="ID" precision="22" scale="0" />
<generator class="sequence" >
<param name="sequence">COL_SEQ</param>
</generator>
</id>
<property name="cdStyle" type="java.lang.Long">
<column name="CD_STYLE" precision="22" scale="0" />
</property>
<property name="cdCode" type="java.lang.String">
<column name="CD_CODE" length="10" />
</property>
<property name="cdChina" type="java.lang.String">
<column name="CD_CHINA" length="60" />
</property>
<property name="cdPy" type="java.lang.String">
<column name="CD_PY" length="10" />
</property>
</class>
</hibernate-mapping>
和这张表的JavaBean.
创建JSP...DynamicLoad.jsp
<%@ page language="java" pageEncoding="GBK"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>DynamicLoad</title>
<meta http-equiv="pragma" c>
<meta http-equiv="cache-control" c>
<meta http-equiv="expires" c>
<meta http-equiv="keywords" c>
<meta http-equiv="description" c>
<style type="text/css">
.mouseOut{
backgroud:#78090;
color:red;
}
.mouseOver{
backgroud:#FFFAFA;
color:#000000;
}
</style>
<script language="javascript" src="<%=request.getContextPath()%>/JS/ajax_func.js"></script><!--ajax函数 -->
<script type="text/javascript">
var completeDiv;
var inputField;
var index = -1; //选择索引
var iCount = 0; //总共的记录数
var currentIndex =0;//当前的索引.
//获取键盘的上下键
function catchKeyBoard()
{
var keyNumber = event.keyCode;
if( keyNumber==40 || keyNumber==38 )
{
if( keyNumber==40 )
{
index ++;
}
else if( keyNumber==38 )
{
index --;
}
if( index < 0 )
{
index = 0;
}
else if( index >= iCount )
{
index = iCount-1;
}
//当前的TR元素背景变红,其他的转为原来的.
var oTRs = document.getElementsByTagName("tr");
currentIndex = index;
for ( var i=0;i<oTRs.length;i++ )
{
if( oTRs == document.getElementById("tr"+index))
{
setMouseOutColor( oTRs );
setMouseOverColor( oTRs );
}
else
{
setMouseOverColor( oTRs );
setMouseOutColor( oTRs );
}
}
}
}
//初始化HTML元素
function initVars()
{
completeDiv = document.getElementById("popup");
inputField = document.getElementById("zone");
}
//从数据库获得地区列表
function findZone()
{
catchKeyBoard();
initVars();
var url = "";
var keyCode = window.event.keyCode;
if( keyCode==13 )
{
//debugger;
var selectZoneValue = document.getElementById("tr"+currentIndex).childNodes[1].innerHTML;
if(selectZoneValue !=null && selectZoneValue.length>0 )
{
setInputFieldValue( document.getElementById("tr"+currentIndex).childNodes[1].innerHTML );
}
}
if( keyCode!=32 &&keyCode!=13 &&keyCode!=116 && keyCode!=17 &&keyCode!=38 &&keyCode!=40 )
{
var re = /^[0-9]+.?[0-9]*$/;
if( re.test(inputField.value) )
{
url = "<%=request.getContextPath()%>/DynamicLoadListAction.do?random="+Math.random()+"&action=dynamicLoadByNumber&zone="+inputField.value;
}
else //英语
{
url = "<%=request.getContextPath()%>/DynamicLoadListAction.do?random="+Math.random()+"&action=dynamicLoadByEnglish&zone="+inputField.value;
}
}
if( inputField.value.length>0 )
{
if( url!='' )
{
send_request("GET",url,null,"XML",setZone);
}
}
else
{
clearZone();
}
}
function setMouseOverColor( obj )
{
if( obj!=null )
{
obj.className='mouseOut';
}
}
function setMouseOutColor( obj )
{
if( obj!=null )
{
obj.className='mouseOver';
}
}
//用户选择完地区以后,给输入框值.
function setInputFieldValue( cdChina )
{
inputField.focus();
inputField.value = cdChina;
//隐藏显示的table.
completeDiv.style.display='none';
}
function setZone()
{
if( http_request.readyState==4 )
{
if( http_request.status==200 )
{
completeDiv.style.display='';
setOffSet();
var responseList = http_request.responseXML;
var zoneList = responseList.getElementsByTagName("zone");
var innerHTML = "";
if( zoneList!=null&&zoneList.length>0 )
{
var innerHTML = "<table id='zoneTable' width=100% bordercolorlight='#80FFFF' border=1 cellspacing=0 cellpadding=0>";
innerHTML += " <TR bgcolor='#C0C0C0'><TD height=25 align=/"center/" class=STYLE3>代码</TD>";
innerHTML += " <TD height=25 align=/"center/" class=STYLE3>中文</TD> ";
innerHTML += " <TD height=25 align=/center/ class=STYLE3>拼音</TD> </TR>";
for( var i=0;i<zoneList.length;i++ )
{
iCount = zoneList.length;
var zone = zoneList;
var cdCode = ( zone.childNodes[0].firstChild==null )?"":zone.childNodes[0].firstChild.data;
var cdChina = ( zone.childNodes[1].firstChild==null )?"":zone.childNodes[1].firstChild.data;
var cdPy = ( zone.childNodes[2].firstChild==null )?"":zone.childNodes[2].firstChild.data;
innerHTML += "<TR id=tr"+i+" onmouseout='setMouseOutColor(this)' onmouseover='setMouseOverColor(this)' onClick=setInputFieldValue('"+cdChina+"') onDblClick=setInputFieldValue('"+cdChina+"')>";
innerHTML += " <TD height=25 align=/"center/" class=STYLE3>"+cdCode+"</TD>";
innerHTML += " <TD height=25 align=/"center/" class=STYLE3>"+cdChina+"</TD>";
innerHTML += " <TD height=25 align=/"center/" class=STYLE3>"+cdPy+"</TD>";
innerHTML += "</TR>";
}
innerHTML +="</table>";
if(innerHTML!='')
{
completeDiv.innerHTML = innerHTML;
}
}
else
{
completeDiv.style.display='none';
}
}
}
}
function setOffSet()
{
var end = inputField.offsetWidth;
var left = calculateOffsetLeft( inputField );
var top = calculateOffsetLeft( inputField ) + inputField.offsetHeight;
completeDiv.style.border="black 1px solid";
completeDiv.style.left = left +130+"px";
completeDiv.style.top = top+20+"px";
completeDiv.style.width = end +"px";
}
function calculateOffsetLeft( field )
{
return calculateOffset( field,"offsetLeft" );
}
function calculcateOffsetTop( field )
{
return calculateOffset( field,"offsetTop" );
}
function calculateOffset( field,attr )
{
var offset = 0;
while( field )
{
offset + field[attr];
field = field.offsetParent;
}
return offset;
}
function populateZone( cell )
{
inputField.value = cell.firstChild.nodeValue;
clearZone();
}
function clearZone()
{
completeDiv.style.display="none";
}
</script>
</head>
<body>
Select Zone...
<input type='text' size='30' id='zone' style='height:20;'>
<div style='position:absolute;' id='popup'/>
</body>
</html>
用myEclipse创建struts,,
配置文件struts-config.xml中的内容为:
<action-mappings >
<action path="/DynamicLoadListAction" scope="request" type="com.huadisz.dynamicload.logic.DynamicLoadListAction">
<forward name="DynamicLoadList" path="/Logic/DynamicLoad.jsp"/>
</action>
</action-mappings>
DynamicLoadListAction.java类
package com.huadisz.dynamicload.logic;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import com.huadi.CodMain;
import com.huadi.comminterface.BuildXML;
import com.huadi.comminterface.ResponseSet;
public class DynamicLoadListAction extends Action implements BuildXML{
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception {
try
{
dynamicLoad(request,response);
}
catch( Exception e )
{
e.printStackTrace();
}
return null;
}
private void dynamicLoad( HttpServletRequest request, HttpServletResponse response ) throws Exception
{
String sPrefix= new String(request.getParameter("zone").getBytes("ISO-8859-1"),"GBK");
String sAction = request.getParameter("action");
if( sPrefix!=null && sAction !=null )
{
ZoneService zs = ZoneService.getInstance();
List returnZoneList = zs.findObject( sPrefix, sAction );
if( returnZoneList.size()>0 )
{
buildXML( request, response, returnZoneList );
}
}
}
public void buildXML( HttpServletRequest request, HttpServletResponse response,List pList ) throws Exception
{
String sPrefix = request.getParameter("zone");
ResponseSet.setResponsePara(response);
Document doc = null;
PrintWriter out = response.getWriter();
Element root = new Element("response");
//把Hibernate查询返回的List做一个缓存。如果在缓存里面已经存在这个List对象,则取出这个对象,然后跟新查询返回的List做比较,
//如果新返回的结果List和缓存中的对象一样,则表示数据库的内容没有发生变化,则直接从localZoneDocCache(doc缓存)中直接取出
//doc对象.如果不一样,则说明数据库内容发生变化,则需要更新缓存中的List和Doc对象.
//如果缓存中还没有包含这个List,则说明是第一次查询,则需要把这个List对象和doc对象放到缓存中.
if( ZoneService.getInstance().localZoneListCache.containsKey( sPrefix ))
{
List zoneList = (List)ZoneService.getInstance().localZoneListCache.get( sPrefix );
if( pList.equals( zoneList ) )
{
doc = (Document)ZoneService.getInstance().localZoneDocCache.get( sPrefix );
}
else
{
doc = new Document();
for( Iterator it = pList.iterator(); it.hasNext(); )
{
CodMain zone = (CodMain)it.next();
Element newElement = new Element("zone");
root.addContent(newElement);
newElement.addContent(new Element("code").addContent( zone.getCdCode()) );
newElement.addContent(new Element("china").addContent( zone.getCdChina()) );
newElement.addContent(new Element("english").addContent( zone.getCdPy()) );
newElement.addContent(new Element("ID").addContent(zone.getId()==null?"":zone.getId().toString()));
}
ZoneService.getInstance().localZoneListCache.remove( sPrefix );
ZoneService.getInstance().localZoneListCache.put( sPrefix, pList );
}
ZoneService.getInstance().localZoneDocCache.remove( sPrefix );
ZoneService.getInstance().localZoneDocCache.put( sPrefix,doc );
}
else
{
doc = new Document();
for( Iterator it = pList.iterator(); it.hasNext(); )
{
CodMain zone = (CodMain)it.next();
Element newElement = new Element("zone");
root.addContent(newElement);
newElement.addContent(new Element("code").addContent(zone.getCdCode()));
newElement.addContent(new Element("china").addContent(zone.getCdChina()));
newElement.addContent(new Element("english").addContent(zone.getCdPy()));
newElement.addContent(new Element("ID").addContent(zone.getId()==null?"":zone.getId().toString()));
}
ZoneService.getInstance().localZoneListCache.put( sPrefix, pList );
ZoneService.getInstance().localZoneDocCache.put( sPrefix, doc );
}
if( !doc.hasRootElement() )
{
doc.addContent(root);
}
XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat().setEncoding("ISO8859-1"));//utf-8
//System.out.println(outputter.outputString(doc));
outputter.output(doc,out);
}
}
ZoneService.java的内容为:
package com.huadisz.dynamicload.logic;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Iterator;
import org.hibernate.Session;
import com.huadi.CodMain;
import com.huadisz.dynamicload.HibernateSessionFactory;
public class ZoneService{
private static ZoneService _self = null;
public static Hashtable< Object,Object> localZoneListCache ;
public static Hashtable <Object,Object> localZoneDocCache;
//localCache maxCapability
private static final int maxCapability = 50;
private ZoneService()
{
localZoneListCache = new Hashtable<Object,Object>();
localZoneDocCache = new Hashtable<Object,Object>();
}
//获得唯一缓存实例
public synchronized static ZoneService getInstance()
{
if( _self==null )
{
_self =new ZoneService();
}
clearLocalCache( localZoneDocCache );
clearLocalCache( localZoneListCache );
return _self;
}
private static void clearLocalCache( Hashtable pLocalCache )
{
if( localZoneDocCache.size()>maxCapability )
{
localZoneDocCache.clear();
}
if( localZoneListCache.size()>maxCapability )
{
localZoneListCache.clear();
}
}
public List findObject( String pPrefix,String pAction )
{
Session session;
List<Object> matches = null;
try{
session = HibernateSessionFactory.getSession();
matches = new ArrayList<Object>();
String strSQL = "";
if( "dynamicLoadByNumber".equals(pAction) )
{
strSQL ="from CodMain WHERE cdCode like '" +pPrefix+"%'";
}
else if( "dynamicLoadByEnglish".equals(pAction))
{
char[] charArray = pPrefix.toCharArray();
for( int i=0;i<charArray.length;i++ )
{
char c = charArray;
if( (int)c >255 )
{
strSQL ="from CodMain WHERE cdChina like '" +pPrefix+"%'";
break;
}
else
{
strSQL ="from CodMain WHERE cdPy like '" +pPrefix+"%'";
break;
}
}
}
Iterator it = session.createQuery(strSQL).iterate();
while( it.hasNext() )
{
CodMain zone=(CodMain)it.next();
matches.add( zone );
}
}
catch( Exception e )
{
e.printStackTrace();
}
return matches;
}
}