一、 概述
AJAX是今年初才問世的新技術,是Asynchronous JavaScript and XML的縮寫。它是一組開發(fā)Web應用程序的技術,它使瀏覽器可以為用戶提供更為自然的瀏覽體驗。每當需要更新時,客戶端Web頁面的修改是異步的和逐步增加的。這樣,AJAX在提交Web頁面內容時大大提高了用戶界面的速度。在基于AJAX的應用程序中沒有必要長時間等待整個頁面的刷新。頁面中需要更新的那部分才進行更改,如果可能的話,更新是在本地完成的,并且是異步的。
J2ee是一種用來開發(fā)分布式系統(tǒng)的體系結構。它主要是用Java類開發(fā)業(yè)務實體。通過JSP來連接應用服務器。
本文開發(fā)一個組織機構管理小系統(tǒng),通過這個實例來介紹如何用Ajax開發(fā)WEB應用程序。本系統(tǒng)具有增加、修改、刪除組織機構的功能。同時給機構分配人員,能增加、修改、刪除人員。
二、 界面設計
樹結構是大多軟件系統(tǒng)中常采用的結構形式。由于樹型結構層次分明、上下級關系清楚、且展開收縮表達信息方便、界面也較美觀,所以是大家熱衷于用此結構。組織機構管理是一般軟件基本具有的。組織機構是指公司的組織結構。集團公司可包括分公子公司,公司下面又有科室。員工歸屬于所在的公司。系統(tǒng)運行后的界面如下:
組織機構主要包括樹結構、組織機構編輯、人員編輯等三大塊,如何分成三塊呢,然而一般樹型結構的窗體常先二塊,樹型結構獨占一塊,另一塊又分成上下二部分,上面是機構編碼,下面是人員編碼。固可以把頁面劃分成如下圖形式:
樹結構區(qū)1 | 組織編碼區(qū)2 |
人員管理區(qū)3 |
顯然我們是通過表來實現(xiàn)。這是一個二行二列的表,且第一、二行的左邊列合并單元格。代碼如下:
< TABLE border="1" width="100%" height="100%"> <TR> <TD rowspan="2"><FONT face="宋體"></FONT></TD> <TD></TD> </TR> <TR> <TD></TD> </TR> </TABLE> |
我們在1區(qū)(單元格)上加上一個DIV,因為DIV可以動態(tài)地滾動,并且可以插入其它控件。DIV的id為"divTree",且風格設置為溢出時自動滾動,寬與高都為100%,及滿區(qū)域。代碼如下:
<div id="divTree" style="width:100%; height:100%;background-color:#f5f5f5;border :1px solid Silver;overflow:auto;"> </div> |
我們在2區(qū)(單元格)上也加上一個DIV,在DIV里再插入一個表格。表格上放下控件,這很簡單,就不詳細說了。
我們在3區(qū)(單元格)上加上一個DIV。此DIV的id為" divContent ",且風格設置為豎直溢出時自動滾動,寬與高都為100%,及滿區(qū)域,此DIV用來裝載人員信息;在DIV里再插入一個表格, 此table的id為" tbList ",是用來輸入、顯示人員作息,同時在此表中插入一些如checkbox 、text、select等控件。說明,表的第二列是用來放人員唯一編號的,不顯示。代碼如下:
<div id="divContent" style="height:100%; overflow-y:auto;" width="100%"> <table id="tbList" border="1" width="100%"> <tr seqNo="1"><td> <table border="1" width="100%"> <tr> <td width="5%"><input type="checkbox" value="on"></input> </td> <td width="0%" style="display:none"> <input type="text" size="20"></input></td> <td width="40%"><input type="text" size="20"></input></td> <td width="25%"> <select size="1" name="D1"> <option value="0">男</option> <option selected="true" value="1">女</option> </select> </td> </tr> </table> </td></tr> </table> </div> |
三、 前端頁面的主要編碼
1. 樹的實現(xiàn)
在WEB上實現(xiàn)樹結構,同樣我們是通過Ajax來實現(xiàn)的。樹上可以顯示自定義的圖標,可以插入、刪除、結點。并且結點可任意移動。這里我們不重點講樹的實現(xiàn)技術,我們已經(jīng)封裝好了,你只要按要求去改動就是了。
1) 鍵接樹型文件
在<head>與</head>之間鍵接我們的與樹有關的文件, 代碼如下:
<link rel="STYLESHEET" type="text/css" href="css/dhtmlXTree.css"> <script src="js/dhtmlXCommon.js"></script> <script src="js/dhtmlXTree.js"></script> |
2) 裝載方法
在頁面的文檔打開時裝載自定義方法, preLoadImages方法實現(xiàn)樹控件的圖標定義,doOnLoad實現(xiàn)樹控件的圖標定義代碼如下:
<body onload="preLoadImages();doOnLoad();"> |
3) 編寫方法
//doOnLoad實現(xiàn)裝載并顯示樹。設置樹屬性等。 function doOnLoad(){ OrgTree=new dhtmlXTreeObject(document.getElementById('divTree'),"100%","100%",0); //dhtmlXTreeObject是樹對象,通過新建對象,指定樹顯示的DIV可定義樹。 OrgTree.setImagePath("imgs/");//設置樹的圖片所在位置 OrgTree.setDragHandler();//設置樹結點拖動 OrgTree.enableDragAndDrop(true) //設置樹結點是否可拖動 OrgTree.setDragHandler(myDragHandler); //設置樹結點拖動時所執(zhí)行的方法 OrgTree.setOnClickHandler(mySelectHandler); //設置樹單擊時所執(zhí)行的方法 //OrgTree.setXMLAutoLoading("Org.jsp");//裝載樹結點數(shù)據(jù)。數(shù)據(jù)來源如Org.jsp所返回的XML格式的字符串,數(shù)據(jù)是動態(tài)裝載,且當展開時才裝載。 OrgTree.loadXML("root.xml?0");//裝載樹結點數(shù)據(jù)。數(shù)據(jù)來源root.xml文件,并且從xml文件的ID號為0處讀取數(shù)據(jù)。 //OrgTree.loadXML("Org.jsp");//裝載樹結點數(shù)據(jù)。數(shù)據(jù)來源如Org.jsp所返回的XML格式的字符串,并且是一次性全部裝載數(shù)據(jù)。 } //preLoadImages方法實現(xiàn)樹控件的圖標定義 function preLoadImages(){ var imSrcAr = new Array("line1.gif","line2.gif","line3.gif","line4.gif","minus2.gif","minus3.gif", "minus4.gif","plus2.gif","plus3.gif","plus4.gif","book.gif","books_open.gif","books_close.gif", "magazine_open.gif","magazine_close.gif","tombs.gif","tombs_mag.gif","book_titel.gif") var imAr = new Array(0); for(var i=0;i<imSrcAr.length;i++){ imAr[imAr.length] = new Image(); imAr[imAr.length-1].src = "imgs/"+imSrcAr[i] } } |
?組織管理的實現(xiàn)
組織可以增加、刪除、編輯。同時當選擇樹結點時應該把組織顯示出來供編輯,查看。為了實現(xiàn)這些功能,你只要按要求去改動就是了。
1) 全局變量的定義
許多地方我們要用到一些公共變量,我們在<script>與</script>之間定義全局變量, 代碼如下:
var OrgTree = null; //組織樹Dom var nextSeq = 0;//人員管理的順序號(流水號) var personDom;//人員Dom var CurrNodeId;//當前結點Id |
2) 初始化
當頁面打開時我們要控件好那部分該顯示,那部分要隱藏。且對全局變量的賦值等,組織類型裝載。在頁面的文檔打開時裝載自定義方法init(), init方法實現(xiàn)初始化。
<body onload="init();"> |
init方法實現(xiàn)如下:
function init(){ //定義personDom為一個XMLDOM'對象 personDom= new ActiveXObject('Microsoft.XMLDOM'); personDom.async = false; //定義stylesheet為一個XMLDOM'對象,且stylesheet為personDom確定顯示風格 stylesheet = new ActiveXObject('Microsoft.XMLDOM'); stylesheet.async = false; stylesheet.load("addOrgPerson.xsl"); //裝載stylesheet的風格定義文件 //裝載組織類型數(shù)據(jù) var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); xmlhttp.open("POST","Org.jsp?mode=GetOrgType", false); xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlhttp.send(); retXml=xmlhttp.responseText; // alert(retXml); //把組織類型插入下拉列表控件中 var OrgDoc = new ActiveXObject('Microsoft.XMLDOM'); OrgDoc.async = false; OrgDoc.loadXML(retXml); var root = OrgDoc.documentElement; oNodeList = root.childNodes; txtType.options.length =oNodeList.length; for (var i=0; i<oNodeList.length; i++) { Item = oNodeList.item(i); var OrgTypeId=Item.childNodes(0).text; var OrgTypeName=Item.childNodes(1).text; txtType.options[i].value=OrgTypeId; txtType.options[i].text=OrgTypeName; // txtType.options[0]. } } |
3) 編寫樹拖動及選擇結點的方法
// myDragHandler實現(xiàn)樹結點拖動時重新指定父子關系。 function myDragHandler(idFrom,idTo){ var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); xmlhttp.open("POST","Org.jsp?mode=moveOrg&orgId=" + idFrom + "&newparentOrgId=" + idTo, false); xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlhttp.send(); retXml=xmlhttp.OrgponseText; return true; } // mySelectHandler實現(xiàn)選擇樹結點對系統(tǒng)的控制,同時顯示組織信息及該組織下的人員。 function mySelectHandler(id){ tbOrg.style.display="block"; divOrgMemo.style.display="none"; divOrgInfo.style.display="none"; if(id==1) { divOrgMemo.style.display="block"; div1.style.display="none"; div2.style.display="none"; div3.style.display="none"; divContent.style.display="none"; div5.style.display="none"; } else { divOrgInfo.style.display="block"; div1.style.display="block"; div2.style.display="block"; div3.style.display="block"; divContent.style.display="block"; div5.style.display="block"; } CurrNodeId=id; //裝載組織信息并顯示在編碼和名稱的文本控件上。 loadOrg(id); //裝載某組織下人員信息 var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); xmlhttp.open("POST","Org.jsp?mode=GetPerson&orgId=" + id, false); xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlhttp.send(); retXml=xmlhttp.responseText; personDom.loadXML (retXml); //給人員信息的每行加上序號 for(var i=0; i<personDom.documentElement.childNodes.length; i++){ personDom.documentElement.childNodes[i].setAttribute("seqNo", nextSeq); nextSeq++; } //人員信息顯示在divContent上面 divContent.innerHTML = personDom.transformNode(stylesheet); }; //裝載組織信息并顯示在編碼和名稱的文本控件上。 function loadOrg(OrgId){ if(OrgId == null){ OrgId = OrgTree.getSelectedItemId(); } if(OrgId == ""){ tbOrg.style.display = "none"; return; } var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); xmlhttp.open("POST","Org.jsp?mode=loadOrg&OrgId=" + OrgId, false); xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlhttp.send(); retXml=xmlhttp.responseText; var OrgDoc = new ActiveXObject('Microsoft.XMLDOM'); OrgDoc.async = false; OrgDoc.loadXML(retXml); if(OrgId != 1){ txtCode.value = OrgDoc.selectSingleNode("http://OrgCode").text; txtName.value = OrgDoc.selectSingleNode("http://OrgName").text; } tbOrg.style.display = "block"; } |
4) 建立組織
組織建立主要是通過調用XMLHTTP對象來實現(xiàn)。我們主要學會如何調用XMLHTTP。組織建立應該在后臺實現(xiàn),把組織信息插入數(shù)據(jù)庫中。這里我們通過JSP來實現(xiàn)。我們的Org.jsp 文件中有個createOrg方法,該方法傳遞一個父ID。
function createOrg(parentOrgId){ var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); xmlhttp.open("POST","Org.jsp?mode=createOrg&parentOrgId=" + parentOrgId, false); xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlhttp.send(); retXml=xmlhttp.responseText; var orgId = (new Number(retXml)).toString(); return orgId; } |
5) 刪除組織
組織刪除同樣是調用Org.jsp 文件中的deleteOrg方法來實現(xiàn),該方法傳遞所刪除的結點ID。function deleteOrg(){
var OrgId = OrgTree.getSelectedItemId();
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("POST","Org.jsp?mode=deleteOrg&OrgId=" + OrgId, false);
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.send();
}
6) 編輯組織
組織修改是調用Org.jsp 文件中的modifyOrg方法來實現(xiàn),該方法傳遞所修改的結點ID。同時修改的數(shù)據(jù)通過自定義的XML格式的字符串傳送,這時通過send字符串來實現(xiàn)。修改前數(shù)據(jù)一律要驗證其合法性,并提示錯誤信息。
3. 人員管理的實現(xiàn)function modifyOrg(){
if(OrgTree.getSelectedItemId() == ""){
return "N";
}
if(txtCode.value == ""){
alert("請輸入編碼!");
return "N";
}
if(txtName.value == ""){
alert("請輸入名稱!");
return"N";
}
var OrgId = OrgTree.getSelectedItemId();
var OrgKind;
//alert(txtType.options[txtType.selectedIndex].value)
var strModify = "<?xml version='1.0' encoding='gb2312'?>" +
"<data>" +
"<OrgCode><![CDATA[" + txtCode.value + "]]></OrgCode>" +
"<OrgName><![CDATA[" + txtName.value + "]]></OrgName>" +
"<OrgKind><![CDATA[" + txtType.options[txtType.selectedIndex].value+ "]]></OrgKind>" +
"</data>";
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("POST","Org.jsp?mode=modifyOrg&OrgId=" + OrgId, false);
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.send(strModify);
OrgTree.setItemText(OrgTree.getSelectedItemId(),txtName.value);
}
人員可以增加、刪除、編輯。同時當選擇樹結點時應該把人員顯示出來供編輯、查看......
1) 增加人員
人員增加實現(xiàn)的原理是在personDom中加入結點peorsone,該結點相當于表的一行,設置屬性。同時在peorsone中不繼地加入其它結點,代表數(shù)據(jù)庫的字段,且必須與XLT文件的標號同名。這些結點相當該行的列。最后在表中插入一行,行上插入一列,并顯示之。function addPerson(){
var seqNo = nextSeq;
nextSeq++;
var peorsonNode = personDom.createNode("1", "peorsone","");
peorsonNode.setAttribute("isNew", "Y");
peorsonNode.setAttribute("isDelete", "N");
peorsonNode.setAttribute("seqNo", seqNo);
personDom.documentElement.appendChild(peorsonNode);
var PersonId= personDom.createNode("1", "personId", "");
peorsonNode.appendChild(PersonId);
var personCode= personDom.createNode("1", "personCode", "");
peorsonNode.appendChild(personCode);
var PersonName= personDom.createNode("1", "personName", "");
peorsonNode.appendChild(PersonName);
var Sex= personDom.createNode("1", "sex", "");
peorsonNode.appendChild(Sex);
var tr = tbList.insertRow(tbList.rows.length);
tr.setAttribute("seqNo", seqNo);
var td = tr.insertCell(0);
td.innerHTML = peorsonNode.transformNode(stylesheet);
}
2) 刪除人員
人員刪除同樣是調用Org.jsp 文件中的deletePerson方法來實現(xiàn),該方法傳遞所刪除的人員ID。如何確定人員ID是通過讀取隱藏的ID,并掃描整個表,看那些被選中。這里我們要注意是提供多項選擇的。function deletePerson(){
for(var i=0; i<tbList.rows.length; i++){
var row=tbList.rows[i].cells[0].children[0].rows[0];
if(row.cells[0].children[0].checked)
{
var personId=row.cells[1].children[0].value;
if(personId>0)
{
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("POST","Org.jsp?mode=deletePerson&personId=" + personId, false);
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.send();
}
tbList.deleteRow(i);
i--;
}
}
}
3) 編輯人員
人員修改我們要判定哪些行被修改了。剛增加但沒保存的行應該是新增而不是修改的。function save(){
if( modifyOrg()=="N")
{
return;
}
for(var i=0; i<tbList.rows.length; i++)
{
var row=tbList.rows[i].cells[0].children[0].rows[0];
var personId=row.cells[1].children[0].value;
var seqNo = tbList.rows[i].getAttribute("seqNo");
var staffNode = personDom.selectSingleNode("http://peorsone[@seqNo='" + seqNo + "']");
var personCode=row.cells[2].children[0].value;
var personName=row.cells[3].children[0].value;
var sex=row.cells[4].children[0].value; //alert(staffN;ode );
if(staffNode.getAttribute("isNew") == "Y")
{
createPerson(CurrNodeId,personCode,personName,sex);
}
else
{
var strXML = "<?xml version='1.0' encoding='gb2312'?>" +
"<data>" +
"<personCode><![CDATA[" + personCode+ "]]></personCode>" +
"<personName><![CDATA[" + personName + "]]></personName>" +
"<sex><![CDATA[" + sex+ "]]></sex>" +
"<personId><![CDATA[" + personId+ "]]></personId>" +
"</data>";
//alert(strXML );
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("POST","Org.jsp?mode=modifyPerson", false);
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.send(strXML );
}
}
}
四、 XML與XSL文件設計
XML是種可擴展的標記語言,它具有開放的、可擴展的、可自描述的語言結構,它已經(jīng)成為網(wǎng)上數(shù)據(jù)和文檔傳輸?shù)臉藴?。XSLT的目的是將信息內容與 Web 顯示分離,HTML 通過按抽象概念(如段落、重點和編號列表)定義顯示來實現(xiàn)設備獨立性。XSLT用來具體顯示控件,設置控件風格。
Ajax主要使用XML和XSLT進行數(shù)據(jù)交換與處理。
1. 樹信息的XML文件(見root.xml文件)
XML是標記語言,元素必須成對出現(xiàn)。樹結構中以tree為根結點,以item為結點體,屬性text指出結點所顯示的文本,id指出唯一的所標識號。
<?xml version='1.0' encoding='gb2312'?> <tree id="0"> <item child="1" text="組織" id="1" > </item> </tree> |
這文件并不是必要的,只是為了系統(tǒng)能獨立運行才加的。事實如果連接了后臺數(shù)據(jù)是不需要的。只要吧OrgTree.loadXML("root.xml?0")改為OrgTree.loadXML("Org.jsp")就可以了。
2. 人員信息XML文件(見peorson.xml文件)
說明![CDATA[]]可在任何顯示任何格式的文本,文本中可插入其它任何字符。這文件也不是必要的。
3. 人員信息展現(xiàn)的xsl文件(見addOrgPerson.xsl文件)
xsl文件同樣是XML格式文件。所以一律遵守XML標準。下面對主要的行講解:
<?xml version="1.0" encoding="gb2312"?> //這是定義xml文件的首行。用來指明版本及字符集 <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl" language="JavaScript"> //這里定義了stylesheet 元素。并指出其國際命名的組織及語言。 <xsl:template match="/"> <xsl:apply-templates select="peorsones"/> </xsl:template> //上面是匹配的規(guī)則。"/"表示從根結開始去匹配。匹配到下面的peorsones標記。這是正則表達式有關的學問。我們只要理解就可以。 <xsl:template match="peorsones"> //當匹配上peorsones時所要做的事情。 <table id="tbList" border="1" width="100%"> //定義一個id為"tbList的表格。此表格是顯示在WEB上的 <xsl:for-each select="peorsone"> //循環(huán)匹配peorsone <tr> //定義tbList表格的一行,并在行上增加一個叫seqNo的屬性名,值為匹配到的seqNo(序號) <xsl:attribute name="seqNo"><xsl:value-of select="@seqNo"/></xsl:attribute> <td> //定義行上的一列,列又去匹配 <xsl:apply-templates select="."/> </td> </tr> </xsl:for-each> </table> </xsl:template> <xsl:template match="peorsone"> <table border="1" width="100%"> <tr> //定義寬為5%的一列,在該列上插入一個checkbox控件 <td width="5%"> <input type="checkbox" value="on" size="10"></input> </td> //定義一個不顯示的列,在該列上插入一個text控件,text的值為匹配到的personId(人員Id) <td style="display:none"> <input type="text" size="25"> <xsl:attribute name="value"><xsl:value-of select="personId"/></xsl:attribute> </input> </td> <td width="30%"> <input type="text" size="20"> <xsl:attribute name="value"><xsl:value-of select="personCode"/></xsl:attribute> </input> </td> <td width="40%"> <input type="text" size="40"> <xsl:attributename="value"><xsl:value-of select="personName"/></xsl:attribute> </input> </td> //定義一個width為28%的列,在該列上插入一個下拉列表select 控件,select的值如果匹配到為0時則為"男",1時則為"女" <td width="28%"> <select size="1"> <option value="0"> <xsl:if test=".[sex=0]"> <xsl:attribute name="selected">true</xsl:attribute> </xsl:if> 男 </option> <option value="1"> <xsl:if test=".[sex=1]"> <xsl:attribute name="selected">true</xsl:attribute> </xsl:if> 女</option> </select> </td> //定義一列,在該列上插入一個button控件,onclick 事件為自定義的方法,該方法傳遞當前單擊的按紐 <td width="*"> <button onclick="openPersonRolePage(this)" style="width: 36; height: 21">角色</button> </td> </tr> </table> </xsl:template> </xsl:stylesheet> |
五、 數(shù)據(jù)接口的實現(xiàn)(見Org.jpg文件)
Org.JSP文件用來在服務器上運行Java的類與前臺web頁之間架起一座橋。取到中間件的接口作用。
這里分析部分代碼:
<%@ page contentType="text/html; charset=GBK" %> <%@ page import="java.sql.*" %> <%@ page import="javax.naming.*" %> <%@ page import="javax.sql.*" %> <%@ page import="tool.*" %> <%@ page import="orgNew.*" %> <%@ page import="org.w3c.dom.*" %> //上面主要是引用一些java類 <% try{ //request.setCharacterEncoding("GBK"); Document doc = XmlTool.createDocumentFromRequest(request); //建立web面文檔請求的文檔對象 Connection conn = ConnTool.getConnectionFromPool(); //獲取請求的方法名 String mode=request.getParameter("mode"); //out.println("ccc"); //如果方法中沒有其它參數(shù)則讀取組織樹數(shù)據(jù) if(mode == null){ /* int OrgId = Integer.parseInt(request.getParameter("id")); String str = orgManager.getChildOrg(OrgId, conn); out.println(str); */ String str = orgManager.getTree(conn); //out.println(str); out.println(str); }else if(mode.equals("createOrg")){ //如果是createOrg方法則建立一個組織 int parentOrgId = Integer.parseInt(request.getParameter("parentOrgId")); //取出傳遞來的第一個參數(shù)parentOrgId int OrgId = orgManager.createOrg(parentOrgId, conn); //調用orgManager 類的createOrg方法來建立一個組織 out.println(OrgId); //返回結果 } conn.close(); } catch(Exception e){ e.printStackTrace(); } %> |
六、 后臺數(shù)據(jù)的實現(xiàn)
1. 數(shù)據(jù)結構的定義
這里,我們主要有三個表。一個是組織結構表,一個是人員表person,一個組織人員關聯(lián)表orgPerson。組織結構表有OrgCode(組織代碼)、OrgName(組織名稱)、orgId(組織Id), parentOrgId(父Id)。人員表有personCode(人員代碼)、personName(人員名稱), sex(性別)、personId(人員Id)。orgPerson表有orgId, personId。
2. 數(shù)據(jù)庫的連接
WEB應用程序常用MySQL作后臺數(shù)據(jù)庫,這是因為MySQL簡單、高效。這里我們也用MySQL作為數(shù)據(jù)庫。Java中用jdbc連接數(shù)據(jù)庫。下面是連接數(shù)據(jù)庫的CODE:
public static Connection getConnectionFromPool() throws Exception { Context ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("java:/erpds"); return ds.getConnection(); } /** * 取數(shù)據(jù)庫鏈接對象 * @return Connection 數(shù)據(jù)庫鏈接對象 * @throws Exception */ /* public static Connection getDirectConnection() throws Exception { Class.forName("com.sybase.jdbc2.jdbc.SybDriver"); String url = "jdbc:sybase:Tds:19.64.13.16:4100/wydb?charset=iso_1"; String user = "sa"; String password = "2860008"; Connection conn = DriverManager.getConnection(url, user, password); return conn; } */ |
. 業(yè)務邏輯層的實現(xiàn)
后臺開發(fā)我們用Java類來實現(xiàn)。這里我們開發(fā)了一個orgNew包,類名為orgManager。此類封裝了與數(shù)據(jù)庫操作有關的方法。通過main可調試程序的正確性。
這里給出了新增加一個組織的全部代碼和通過XML取得樹結構信息的代碼,樹結構通過遞歸實現(xiàn)。
package orgNew;// Java類所打的包 import tool.*; import java.sql.*; import java.util.*; // 引用Java類的 public class orgManager { public orgManager() { } public static void main(String[] args) throws Exception { Connection conn = tool.ConnTool.getDirectConnection();// 引用數(shù)據(jù)訪問類 conn.setAutoCommit(false); orgManager orgManager1 = new orgManager(); orgManager1.createOrg(0, conn); //測試建立組織是否正確 } //建立一個組織 public static int createOrg(int parentOrgId, Connection conn) throws Exception { String sql = "insert into Org (OrgName, parentOrgId) values('新組織', ?)"; PreparedStatement pstat = conn.prepareStatement(sql); pstat.setInt(1, parentOrgId); pstat.executeUpdate(); pstat.close(); Statement stat = conn.createStatement(); String sql2 = "select max(OrgId) from Org"; ResultSet rs = stat.executeQuery(sql2); rs.next(); int OrgId = rs.getInt(1); rs.close(); stat.close(); System.out.println(OrgId); return OrgId; } } //通過遞歸得到組織信息的XML格式的數(shù)據(jù) public static String getTree(Connection conn) throws Exception { StringBuffer ret = new StringBuffer();//定義可緩沖的字符流 ret.append("<?xml version='1.0' encoding='gb2312'?><tree id='0'>");//定義XML格式的頭信息 ret.append(" <item child='1' text='組織' id='1' >");//插入結點體。注樹結點以item為標記 ret.append(getChildTree(1, conn)); ret.append("</item>");//結點體結束標記 ret.append("</tree>");//樹結束標記 return ret.toString();//返回字符流 } public static String getChildTree(int OrgId, Connection conn) throws Exception { StringBuffer ret = new StringBuffer(); String sql = "select a.OrgId, a.OrgName, a.OrgCode,count(b.parentOrgId) from Org a " + "left join Org b on a.OrgId = b.parentOrgId " + "where a.parentOrgId = ? " + "group by a.OrgId, a.OrgName"; PreparedStatement pstat = conn.prepareStatement(sql); pstat.setInt(1, OrgId); ResultSet rs = pstat.executeQuery(); while (rs.next()) { int childOrgId = rs.getInt(1); String childOrgName = rs.getString(2); String childOrgCode = rs.getString(3); if (childOrgCode == null) { childOrgCode = " "; } if (childOrgName == null) { childOrgName = "新組織"; } int childCount = rs.getInt(3); if (childCount > 0) { childCount = 1; } ret.append("<item child='" + childCount + "' text='" + childOrgName + "' id='" +childOrgId + "' code='"+childOrgCode+"'>"); ret.append(getChildTree(childOrgId, conn)); ret.append("</item>"); } rs.close(); pstat.close(); return ret.toString(); } |
其它代碼見orgManager.java文件。
七、 總結
本文件通過一個實例全面介紹了Ajax開發(fā)的各個細節(jié)。通過與J2ee的結合來實現(xiàn)三層分布式開發(fā)的層次劃分,后臺與前端的調用。數(shù)據(jù)的讀取、訪問及展現(xiàn)。
通過這個實例,我們可見,Ajax使WEB中的界面與應用分離。數(shù)據(jù)與呈現(xiàn)分離的分離,有利于分工合作、減少非技術人員對頁面的修改造成的WEB應用程序錯誤、提高效率、也更加適用于現(xiàn)在的發(fā)布系統(tǒng)。也可以把以前的一些服務器負擔的工作轉嫁到客戶端,利于客戶端閑置的處理能力來處理。
Ajax是傳統(tǒng)WEB應用程序的一個轉變。以前是服務器每次生成HTML頁面并返回給客戶端(瀏覽器)。Ajax理念的出現(xiàn),揭開了無刷新更新頁面時代的序幕,并有代替?zhèn)鹘y(tǒng)web開發(fā)中采用form(表單)遞交方式更新web頁面的趨勢,可以算是一個里程碑。
總之,Ajax適用于交互較多,頻繁讀數(shù)據(jù),數(shù)據(jù)分類良好的WEB應用。