http://developer.51cto.com/developer/51cto-salon-13/
張昊J-Hi(http://www.j-hi.net) |
http://developer.51cto.com/developer/51cto-salon-13/ 描述:在DWZ版中lookup的處理機制與經典的完全不同,對于lookup有兩種展現形式,一種是通過點擊lookup圖標彈出對話框后帶回選中的值,另一種是通過在文本框中輸入相應信息從而實現聯機式的查找帶回效果。從實現目的來看,無非是讓lookup的實體的主鍵值帶回到hidden的一個元素中,而其它值只是作為顯示參考之用,與底層的數據庫結構與數據庫表無關。一個完整的lookup由如下html元素構成:1)一個hidden用于保存帶回實體主鍵的ID值;如果要實現缺省的lookup過濾或排序可以相應的pageInfo的hidden元素,具體實現方式的用例參見《HowTo手冊》;2)n個text用于顯示帶回的多個數據帶回項(注意:因為帶回的數據項與數據訪問層也就是數據庫表無關,因此每個text的name都有一個hi_作為前綴);3)一個lookup有且只有一個主帶回項,只有主帶回項的文本框是可編輯的并且只有主帶回項會有lookup圖標也就是html的中的a元素。
場景描述:一個會員編輯頁面要指定該會員所在的省份、城市、地區,要求在選擇省份后會自動過濾該省份的城市,地區以此類推。 以下所有步驟只是修改OrganizationEdit.jsp文件,即可 步驟一、為省份的主帶回項加callback回調方法,并在實現該js方法 <input type="text" class="textInput" name="organization.hi_province.name" value="${organization.province.name}" callback="processProvince" function processProvince(json){ document.getElementById("pageInfo.province.f_id").value = json.id; } //該方法的目的是在選擇某個省份后將該省份的ID值放到指定的hidden元素中 步驟二、為城市加一個用于過濾的hidden元素,注意:processProvince()方法中的賦值語句就是該hidden元素;用于過濾的name必須與PageInfo的具體類相對應;必須要指定lookupGroup與lookupName <input type="hidden" lookupGroup="organization" lookupName="city" name="pageInfo.province.f_id" id="pageInfo.province.f_id" value=""/> 步驟三、為城市的主帶回項加callback回調方法,并在實現該js方法 <input type="text" class="textInput" name="organization.hi_city.name" value="${organization.city.name}" callback="processCity" function processCity(json){ document.getElementById("pageInfo.city.f_id").value = json.id; } 步驟四、為地區加一個用于過濾的hidden元素 <input type="hidden" name="pageInfo.city.f_id" id="pageInfo.city.f_id" lookupGroup="organization" lookupName="region" value=""/> 總結:級聯下拉實際上是lookup的一個變種形式,主要的思想是為你要級聯的下拉的lookup加入過濾項,例如在城市加一個省份的過濾項,在選擇省份時后,會通過回調方法將這個過濾項的值存到該過濾項中。這樣逐級過濾就實現了級聯下拉的效果. 大家可以簡單將J-Hi建模工具理解為數據庫的E-R圖,每個實體就對應一個數據庫的表,而實體中每個屬性就對應數據庫表的一個字段。那么實體與實體之間的關系或表與表的關系又是如何描述的呢? 對于數據庫表的關系大體可分為,如下幾種形式 many-to-one:相當于一個數據庫表的字段(外鍵)對應另一張數據庫表的主鍵,對于J-Hi來說,就是一個lookup(查找帶回)。即一個實體中的某個屬性是lookup類型,這個屬性會lookup另一個實體。對lookup定義的操作步驟請參見“應用開發視頻”。頁面中的展示形式,例如你有一個報銷單,要lookup用戶,那么平臺就會自動將用戶的名稱帶回來,并在數據庫中將用戶的ID值保存到報銷單表的相應字段中。
one-to-many:相當于一個數據庫表下面會有一個或多個明細表,例如一個報銷單是主表而報銷單明細是明細表。在數據庫端的實現形式為,在明細表中有一個主表的外鍵ID字段。在J-Hi中我們稱之為引用,具體操作見聯機幫助
one-to-one:所謂一對一的關系在數據庫上的理解為,B表每加一條記錄A表也會隨著增加一條記錄,在J-Hi中的表現形式為實體繼承 對于實體的繼承,不只是簡單的表one-to-one關系,實體的繼承還包括所有的java類的繼承關系,JSP頁面的整合等等
many-to-many:多對多是一種復雜的表關系,J-Hi是通過中間過渡表來實現這種多對多的關系,例如一個項目可以有多個成員,而一個成員又有可能在多個項目中,建模的圖為 1.前臺頁面: //自定義一個回調函數ajaxDone <form action="expert_BaseInformationSave.action?navTabId=expert_BaseInformationList&callbackType=closeCurrent&ajax=1" method="post" class="pageForm required-validate" onsubmit="return validateCallback(this, ajaxDone)">
//回調函數 <script type="text/javascript"> function ajaxDone(json) { alert(json.expert.name); } </script>
2.后臺代碼: public class Expert_BaseInformationSaveAction extends BaseAction implements SynchronizationData{ private Expert_BaseInformation expert_BaseInformation; private JSONObject json;
public String execute() throws Exception { Expert_BaseInformationManager expert_BaseInformationMgr = (Expert_BaseInformationManager) SpringContextHolder.getBean(Expert_BaseInformation.class); if(super.perExecute(expert_BaseInformation)!= null) return returnCommand(); expert_BaseInformationMgr.saveExpert_BaseInformation(expert_BaseInformation); super.postExecute(expert_BaseInformation); json = new JSONObject("expert", expert_BaseInformation, "name, gender, unit");
return "json"; }
public Expert_BaseInformation getExpert_BaseInformation() { return expert_BaseInformation; }
public void setExpert_BaseInformation(Expert_BaseInformation expert_BaseInformation) { this.expert_BaseInformation = expert_BaseInformation; }
public JSONObject getJson() { return json; } }
注意:action中必須定義public JSONObject getJson() { return json; }, 否則前臺無法獲取json數據。 注:該文檔由J-Hi愛好者"笨笨"提供,他的QQ號為289542213,歡迎大家與他在技術上多多交流 本文主要講解J-hi中樹的過濾。以員工部門樹為例。 要求在點擊某個員工時,能夠查看到該員工所在的部門。
![]()
圖1-部門樹 下圖2是所有員工列表: 圖-2 當點擊王五時,顯示王五所在的部門結構樹如圖3。 圖-3 主要代碼部分: 1、Jsp超鏈接代碼: <a href="tree.action?menuName=orgList&orgId=${item.org.id}" target="dialog">${item.org.orgName}</a> 注意:orgId是動態傳入的參數,這里指該員工所在的部門編號。 2、在himenu-config.xml中配置部門樹的后面加上這么一段 <void property="filter"> <string>org.cis.filter.orgCollectionProcessor</string> </void> 注意:string標簽內的是寫過濾數據的類。對樹的數據進行過濾,提供兩種接口方式對數據進行過濾 MenuFilterProcessor 在獲取數據之前填加過濾器;MenuCollectionProcessor 在獲取數據之后再對數據做整理.具體方法查看java-doc的API。 而例子的orgCollectionProcessor類代碼: public class orgCollectionProcessor implements MenuCollectionProcessor {
public Collection getCollection(Collection coll, Map<String, String> map) { // TODO Auto-generated method stub //coll - 當前節點下一級節點的數據集合 //map 動態的傳入數據,以map的形式 //傳入一個員工的所在的部門Id,返回該員工所在的部門結構樹 int orgId=Integer.parseInt(map.get("orgId").toString()); for (Iterator iterator = coll.iterator(); iterator.hasNext();) { Object obj = (Object) iterator.next(); if(obj instanceof HiOrg){ HiOrg hiorg = (HiOrg)obj; if(hiorg.getId()!=orgId) { iterator.remove(); coll.remove(obj); } } } return coll; } } 注:該文檔由J-Hi愛好者"無可"提供,他的QQ號為924372739,歡迎大家與他在技術上多多交流 樹形菜單能很好的呈現菜單項之前的從屬關系,結構清晰明了。J-hi平臺提供了自定義樹形菜單的功能,通過簡單的配置即可實現。 本文主要介紹通過樹形菜單選擇帶回節點值的實現方法。以選擇帶回行政區劃位置為例。 數據庫表設計:默認帶回頁選擇界面:通過jhi自動生成代碼的功能,對于lookup xzqhwz的字段默認是如上帶回頁面,顯然并不能表現行政區劃位置之間的主從關系。 樹形帶回頁面:而如果實現如下頁面的展示,將會清晰方便許多。 雙擊即可帶回節點,也可通過配置帶回節點的各級父節點。 下面是配置的方法: 配置方法:修改xml修改C:"Program"hi-studio"eclipse"workspace"earch5"web"WEB-INF"config"himenu-config.xml 在代碼末尾: </object> </java> 之前插入:(注意修改其中參數) <void method="put"> <string>zdtree</string> <object class="org.hi.base.menu.strutsmenu.WebDynamicMenuDefine"> <void property="keymap"> <object class="java.util.HashMap"> <void method="put"> <string>id</string> <string>parentxzqhwz</string> </void> </object> </void> <void property="parent"> <string>id</string> </void> <void property="child"> <string>parentxzqhwz</string> </void> <void property="childValue"> <int>0</int> <! 新版本jhi應為:<string>0</string> > </void> <void property="menuName"> <string>zdtree</string> </void> <void property="beanName"> <string>org.hi.zdtree.model.Xzqhwz</string> </void> <void property="submenuName"> <string>zdtree</string> </void> <void property="title"> <string>行政區劃位置</string> </void> <void property="titleField"> <string>xzqhwz</string> </void> <void property="needShow"> <boolean>true</boolean> </void> <void property="javascript"> <string> function backAgent(id,orgName){ if(opener.document.getElementById('yzjbxx.xzqhwz')!=null){ opener.document.getElementById('yzjbxx.xzqhwz').value=orgName; } <!帶回到相應的頁面的相應文本框。 > else{ opener.document.getElementById('xzqhwz.pxzqhwz').value=orgName; opener.document.getElementById('xzqhwz.parentxzqhwz.id').value=id; window.close(); } } </string> </void> <void property="action"> <string>{js}backAgent([#id],"'[#xzqhwz]"');</string> <!在樹型結構上通過雙擊一個節點,獲取帶回該節點的各級上節點 <string>{js}backAgent([#id],"'[#parentxzqhwz.parentxzqhwz.parentxzqhwz.xzqhwz][#parentxzqhwz.parentxzqhwz.xzqhwz][#parentxzqhwz.xzqhwz][#xzqhwz]"');</string> > </void> </object> </void> 修改XzqhwzEdit.jsp頁面將C:"Program"hi-studio"eclipse"workspace"earch5"web"zdtree"XzqhwzEdit.jsp中 onclick="xzqhwz_lookupPOP('parentxzqhwz')" 改為: onclick="window.open('/tree.action?menuName=zdtree','部門','width=300,height=500,left=10,top=20,location=no,status=no')" 這樣,到Xzqhwz的頁面,點擊父節點的帶回按鈕即可看到效果,同樣lookup到xzqhwz字段的地方也修改Edit.jsp頁面的onclick動作就行啦。
該文檔是對J-Hi樹形的入門級介紹,J-Hi的樹功能還有:節點的過濾,lazy加載,一個節點可以多個圖標、復選框效果,多個實體組合形成一棵樹,我們將在以后繼續講解
注:該文檔由J-Hi愛好者"馮思豪"提供,他的QQ號為382600911,歡迎大家與他在技術上多多交流
J-Hi平臺在考慮到開發時與發布后對信息、安全、效率等方面的要求不同,從而提供了設置開發模式與發布模式的開關。這個開關配置在src下的hiFrameworkConfig.properties文件中。
hi.depolyment.published=true
下面讓我們就這個開關項做如下分析,如果值為true,也就是發布模式,它到底會影響哪些東西:信息內容 1)菜單中“權限”、“權限資源”將不在顯示,因為一旦將做好的項目發布后,這些信息是不能讓客戶維護的。 2)菜單中“觸發器”、“消息管理”將不可見,因為一旦定時服務設定好,一般來說客戶很少會調整,即使是調整也應該是由開發人員來調整觸發的周期與頻率。對于消息管理也是一樣。 3) 整個“國際化”菜單項全部不顯示,這其中包括“多語言參數”、“語言編碼”、“時區”,原因這些內部均應該在開發過程中將信息內容一并編輯完成。比如有一個語言編碼就要有一套多語言參數與之對應,因些一旦系統上線,所有國際化部分的維護功能也應該同時完成。 4)“應用配置”列表中,“刪除”圖標將不再顯示,因為如果系統上線,系統中的一些基礎配置項是不能刪除,而只能更改的 對于這個功能的控制,是在main.jsp中,加入一個變量,代碼如下 <%// 是否已發布的開關,其目的是如果為true則關閉那些對終端用戶不可見的功能按鈕 %>
建議大家以后在自己采用J-Hi開發的系統中也可以采用該方式來控制頁面,這樣就可以做到即不影響開發,而在項目提交給用戶時同樣保證某些只在開發時才能用到的按鈕或功能,只要改變一個開關就可以控制。 <ws:set name="published" value="@org.hi.framework.HiConfigHolder@getPublished()" /> 安全 如果采用了發布模式后,頁面提交的URL將會被加密,而開發模式URL則是以明文顯示,開關則試前后URL的效果如下: http://localhost:8080/hiUserEdit.action?hiUser.id=1
由此可以看出URL問號后的參數部分全部通過了加密處理,這樣使您做出的系統更安全,通過使別人URL分析不出你要獲取的信息參與也推導不出系統的結構http://localhost:8080/hiUserEdit.action?cf4a9619dd97fc2689fb63048237404f 效率 1)如果是發布模式,DWZ版的所有js文件將采用壓縮的文件,而非一個一個的離散文件,這樣系統的傳輸的內容會更少,具體的方式參見styles.jsp文件 2)如果是發布模式,系統在啟動時一次性加載枚舉實體、枚舉值、多語言參數、應用配置這些常量性的信息進入緩存,在取這些信息時系統會自動從緩沖中取而并非每都要查詢數據庫。舉例來說,性別是一個下拉的枚舉,如果是發布模式只直接從緩沖區中取數據,而如果是開發模式它就會去數據庫中取數據,如果是一個人員列表,那么有幾個要顯示枚舉的地方就要去數據庫取幾次。因此開發模式的運行效率要遠遠低于發布模式,但開發模式更有實效性,只要數據有任何變化都可以實體的反應出來,即使是在同一個事務中,而發布模式只能在一個事務完成之后再能做數據同步處理(即內存與數據庫之間的數據同步)
J-Hi與DWZ兩個國內優秀的開源項目強強聯合,攜手推出J-Hi4DWZ版。
登錄頁面 首頁面 J-Hi生成器生成的編輯頁面:使你不用寫任何一行代碼就能實現富文本編輯、頁面校驗、上傳附件、自動帶回、主從表編輯等功能
角色分派頁面:可以看到平臺提供左側樹型結構(無需任何編碼,簡單配置即可)
當然樹還可以做成是彈出帶回值效果
更新日志: 1、融合DWZ富客戶端做前端頁面展示 2、支持跨瀏覽器包括IE6\7\8\9 FireFox等 3、實現webwork與struts2無配置文件解決方案 4、插件增加懸浮聯機幫助 5、支持實體復制
1、解決登錄用戶的信息與數據庫信息不一致的問題 2、解決多語言標簽緩存問題 3、生成時如果有從表不在菜單顯示 4、解決在struts下角色、權限、人員會有垃圾數據問題 5、增加二個對菜單樹的過濾的接口,及回調實現 6、修改了對菜單樹非整數型的配置方法 7、解決加刪除標識符的實體未做過濾的問題 8、優化了webwork和struts的基類BaseAction
開發人員列表:
測試人員列表: 羅天文、伏占才、宋藝、肖金華、張昊
下載地址:http://code.google.com/p/j-hi/downloads/list J-Hi:http://code.google.com/p/j-hi/ DWZ:http://code.google.com/p/dwz/
線上交流:133176937(滿),133177634(滿),133178083,134232577
相關文章:寫在J-Hi for DWZ版發布的前夜
下一步計劃: 1) 融合SpringJDBC 2) 支持實體從數據庫反向導入并生成代碼 3) 支持樹形組件的可視化配置
1、快速上手,降低學習曲線 對于剛剛接觸J-Hi的人來說,它上手很容易,我們為每一個功能點都提供了懸浮幫助功能,即使沒有任何資料(當然我們已提供了視頻與開發文檔),您也可以通過向導與幫助在十分鐘之內就可以創建出您自己的項目原型。 其次J-Hi平臺采用的大都是大家耳熟能詳的主流框架與技術,如果您對主流的框架有所了解,那么對J-Hi的學習就沒有任何阻力了。 2、快速搭建開發環境 也許您因為項目或自身開發團隊的不同會采用不同的框架技術,例如您團隊中對struts2熟悉的人遠遠要比掌握webwork的工程師要多,或者在您的項目中統計分析的功能很多,您要考慮ORM的效率問題,而不得不放棄hibernate而采用ibatis或springJDBC,也許您還要考慮數據庫問題等等。在搭建開發環境您一定會考慮很多因素,盡管搭建開發環境并不復雜,但還是不夠自動化,還要手動的配置,費時費力。J-Hi為快速搭建開發環境提供合理的解決方案,您可以按需求動態的搭建開發環境。 在此您可以選擇不同的ORM框架 在此您可以選擇不同的表現層框架 在此您可以選擇不同的頁面框架,并且我們提供了“預覽”讓您在搭建開發環境之前就可以看到搭建后的頁面顯示效果 在此您可以選擇不同的數據庫。 3、快速生成所有代碼 通過建立或導入模式,您可以快速的生成所有代碼與文件,并且在生成時會根據您選擇的框架技術與數據庫的不同而自動適配。 當然您還可以有選擇的生成部分代碼文件,例如只生成JSP頁面,或只生成java代碼。生成的java代碼結構如下(因為我選擇的框架是ibatis3+struts2,所以平臺會自動匹配只生成與這兩個框架相關的類文件,而不會生成無用的其它框架的東西): 4、快速解決在業務需求中的技術難點 一般我們在做項目開發時,總是要等到項目開發的中、后期才能去解決業務核心問題,因此很造成無法合理估計項目的技術風險。原因是復雜的業務總是要等到基礎模塊建好后才能進入到開發階段,從而使解決核心的技術問題置后。我們以一個報銷為例來做個簡單說明,比如報銷在審核后的業務邏輯很復雜并且有可能還要涉及到與其它的系統對接。一般來說我們總是要等到這個報銷單建好,起碼要有最基本的增刪查改功能(即使沒有頁面也要有后臺的代碼)后才能進入到核心業務的開發,這就加大的技術風險,因為我們會很早的發現問題,但解決這些問題卻遠遠的落后于發現這個問題,甚至到了開發的中、后期因為技術問題在底層上還要一改再改。而使用J-Hi可以很快的進入到業務核心的技術上,因為只要生成,基礎功能就已經提供,甚至平臺還為您提供了單元測試用例類,從而使您可以直指業務核心,將項目風險控制在最低。 5、通過提供通用的組件 平臺提供了很多通用業務組件,例如組織機構、角色權限、報表、定時任務、菜單管理、日志管理、系統配置、附件上傳等等,除此之外平臺還提供了一些純技術組件,例如樹型結構、java腳本工具、編碼生成器、可選擇性的返回JSON對象等等。這些通用的業務組件與技術組件可以為您在開發過程節省很多時間,隨需使用,從而大大降低開發速度。 6、通過服務的復用性提高開發速度 在介紹平臺的服務復用性之前,讓我們來舉個例子。比如您做了一個OA項目其中有一個模塊是報銷管理這個模塊很成熟,您已經在OA系統中應用了很久。現在又有一個ERP系統,您想把這個成熟的報銷管理復制到ERP系統中,這樣這個功能就不用在ERP系統中再做開發了。對于平臺來說這就是服務的復用性,我們提供了一整套對服務復用性的解決方案,并且有自己的可視化工具。 我們叫它J-Hi整合工具,是用C#做的。它的作用: 1)可視化導入/導出數據庫,并同時實現跨數據庫,例如您可以在mysql上開發(導出),開發完將所有的數據遷移到oracle上(導入)。 2)發布器,可視化將您開發的模塊或系統自動發布成一個發布包(包括數據庫、jar、文件[jsp、js、圖片、配置文件等]還包括文件的片段[例如修改web.xml文件中的一部分內容]) 3)部署器,將發布包部署到開發的工程中,部署的內容見發布器的描述 4)實施器,對應的生產系統,我們通過FTP,將相應的文件與數據庫自動部署到生產系統中 7、快速的部署與遷移 也許您正在為客戶要求從SQLServer數據庫改為Oracle而感到苦惱,因為這要做大量的數據遷移工作,或許您反復的將修改后的bug部署到生產環境中而郁悶,我想J-Hi通過它的整合工具為您提供了便捷的方式。具體的實現方式請參見上一節的介紹 8、開發人員可以快速的接手別人的工作 因為使用J-Hi開發,生成的代碼與文件的風格都是相同的,在哪里寫業務邏輯應該怎么寫?在哪里要改頁面應該怎么做?想要到哪張數據庫表或表與類的對應關系?包括生成的類、JSP文件、配置文件的命名規則都是統一的。因此一個新人加入團隊會很容易的上手并進入工作狀態,即使是修改別人寫過的代碼,也會很快速的定位到相應要修改的位置。 9、快速解決需求變更 對于項目開發來說,項目的需求變更是很正常的事情,對于有經驗的項目經理來說,如果一個項目從未發生過需求變更過反而是不正常了:)一但需求變更大多都要改數據庫表,如果是已運行很穩定的系統,這種變更真是要命。J-Hi為此也提供了自己的解決方案,對于簡單表變更,平臺只要對單個實體生成就可以了。如果是復雜的變更,我們還提供繼承實體的解決方案,也就是說原來的所有代碼與表結構都不變,通過實體繼承J-Hi會從數據庫表到java類再到JSP頁面形成一整套繼承關系,從而保證以前功能的穩定性。這個說來好象很玄妙,讓我們舉例說明。比如你有一個部門表,N多信息都與它有聯系,而且做了很多的業務處理,現在客戶要求在部門表中加另一些信息。對你來說可能會為部門表中加字段,由此而帶來所有類的變化與頁面的變化,而這套系統已經很穩定已經用了一、兩年了,開發人員都已經離開了公司,這樣接手的人要讀懂全部代碼才有可能改,這樣就造成開發速度的大大降低。平臺提供了另一種解決方案:不動以前的任何東西,相關于在原有的基礎上打上一塊補丁。再做一張表,讓這張表與部門表形成one to one的關系,而類無論是POJO、DAO、Service都繼承自部門相應類作為父類,同時在JSP頁面上也會繼承所有部門的所有元素,這樣就形成了實體繼承關系,這就好比設計模式中最基本的“開閉原則”,對于所有的新生功能是開放的,而對于已有的老功能是關閉的,可以完全把老的功能視為一個黑箱。這樣即能保證已有功能的穩定性,又能加入新的功能做為補充。 |