<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    張昊

    J-Hi(http://www.j-hi.net)

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      45 Posts :: 1 Stories :: 110 Comments :: 0 Trackbacks

    置頂隨筆 #

    http://developer.51cto.com/developer/51cto-salon-13/





    視頻點播
    《Java快速開發的分析與探索》[上](張昊)
    《Java快速開發的分析與探索》[下](張昊)
    《Java快速開發平臺使用》(肖金華)
    用戶交流與問答環節

    推薦閱讀


    51CTO電子雜志《開發月刊》

    51CTO開發頻道推出《開發月刊》電子雜志。主要內容涵蓋Java、.NET、WEB開發、數據庫和移動開發等等。從技術細節到項目管理,方方面面為開發者服務。



    往期回顧
     
    51CTO技術沙龍之IDC挑選運維經驗談
    51CTO技術沙龍之掌握網絡流量分析與系統監控
    51CTO技術沙龍之企業服務器安全攻與防
    51CTO技術沙龍之Linux系統安全
    51CTO技術沙龍之解析中小企業網絡運維
    51CTO技術沙龍之Web開發前沿技術探索與實戰
    51CTO技術沙龍之大型網站PHP開發之道
    51CTO技術沙龍之 IT技術人,茫茫職業人生路
    51CTO技術沙龍之 如何快速定位黑客攻擊
    51CTO技術沙龍之 關于企業安全運維的那些事兒
    51CTO技術沙龍之 站在業務擴展的角度看Linux運維技術
    51CTO技術沙龍之 從菜鳥到CTO,你的目標需要管理
    51CTO技術沙龍之 兩小時成為反掛馬達人
    51CTO技術沙龍之 全方位解析虛擬化
    51CTO技術沙龍之 企業基礎網絡與核心服務搭建
    51CTO技術沙龍之 負載均衡2期

    沙龍導讀與PPT下載

    51CTO技術沙龍第十三期總結:Java快速開發之路
    在2011年9月3日下午51CTO舉辦的第13期51CTO技術沙龍中,有幸請到Java開源平臺——J-Hi的兩位創始人張昊老師和肖金華老師。二位講師分別從理論和實戰來為大家介紹J-Hi,打開Java快速開發之路。查看
    PPT下載:《Java快速開發的分析與探索》(張昊)
    詳細分析快速開發與傳統開發方式在開發形式上的差異,兩個模式所存在的風險及如何規避這些風險,并對開發效率、成本及開發規范做出對比。最后闡述為什么快速開發將是以后軟件開發的趨勢。 PPT下載 | 視頻下載
    《Java快速開發平臺使用》(肖金華)
    主要介紹怎樣架構你的互聯網應用才能顯得不是那么草根,基于弱關系理論的結構化數據存儲與程序設計高性能的數據緩沖層讓你的數據離CPU再近一些。如何定位應用的性能瓶頸以及系能優化的思路。 視頻下載
     

    本期講師介紹

     
     
    J-Hi快速開發平臺團隊核心成員 張昊
    軟迅博技術發展有限公司首席架構師,開源J-Hi快速開發平臺團隊核心成員,平臺項目的主要發起者與組織者。
    軟迅博技術發展有限公司項目總監 肖金華
    開源J-Hi快速開發平臺團隊核心成員,十一年軟件開發經驗,帶領完成過多個大型項目。熟悉保險及電力行業,曾任某IT公司保險業務線架構師。
     
     

    相關Java專題


    51CTO開發頻道專訪J-Hi快速開發平臺團隊核心成員張昊先生,向大家講述J-Hi快速開發平臺從創意到研發再到產品的完整脈絡和技術領域以及對廣大愛好者的一些建議。


     

    2011年7月7日,甲骨文舉行了生活的全球性活動,以慶祝即將到來的Java 7推出。標準版Java SE 7是對Java社區和甲骨文對開發語言和技術持續承諾的一種肯定。

      

    沙龍現場照片


     
     
     
     
     
     
     
     
     
     
     



    posted @ 2011-09-16 23:48 張昊 閱讀(1195) | 評論 (2)編輯 收藏

    http://weibo.com/javahi
    posted @ 2011-09-09 16:26 張昊 閱讀(879) | 評論 (1)編輯 收藏


    描述:在DWZ版中lookup的處理機制與經典的完全不同,對于lookup有兩種展現形式,一種是通過點擊lookup圖標彈出對話框后帶回選中的值,另一種是通過在文本框中輸入相應信息從而實現聯機式的查找帶回效果。從實現目的來看,無非是讓lookup的實體的主鍵值帶回到hidden的一個元素中,而其它值只是作為顯示參考之用,與底層的數據庫結構與數據庫表無關。一個完整的lookup由如下html元素構成:1)一個hidden用于保存帶回實體主鍵的ID值;如果要實現缺省的lookup過濾或排序可以相應的pageInfohidden元素,具體實現方式的用例參見《HowTo手冊》;2ntext用于顯示帶回的多個數據帶回項(注意:因為帶回的數據項與數據訪問層也就是數據庫表無關,因此每個textname都有一個hi_作為前綴);3)一個lookup有且只有一個主帶回項,只有主帶回項的文本框是可編輯的并且只有主帶回項會有lookup圖標也就是html的中的a元素。

    擴展屬性名

    lookupGroup

    lookup組可以理解為當前實體的名字,如果當前lookup組件是主實體中,則lookupGroup就是實體名,如果當前lookup組件在從實體(也就是明細表的lookup)中,則lookupGroup就是明細的集合屬性名

    lookupName

    lookup名可以理解為當前lookup實體的屬性名。從整體的DWZ框架來分析,實際上所有的tab都在一個IE窗口,也就是說JS文件在打開瀏覽器只會加載一次。這就產生了必須要保證每一個html元素的唯一性,即使是在不同的tab下也是如此。對于lookup來說,是通過lookupGroup+lookupName來確定元素的唯一性的。

    suggestClass

    主帶回項才會有該屬性,實現聯想查找帶回

    lookup實體的POJO類的全限定名

    searchFields

    查詢過濾的屬性名列表,以逗號分隔。例如帶回HiUser,該屬性的值為”fullName,userNum”,在文本框中001則平臺會查詢姓名或者是編號為001的所有用戶

    callback

    回調方法名,在查找帶回值后系統會回調該屬性的值的方法,以實現您對帶回后的特殊處理。例如callback=fun,那么在帶回值后系統會自動調用fun方法,并會自動傳入兩個參數fun(json,index),其中json:是帶回的完整json對象,index:是索引值,主要用于明細的帶回時要提供是第幾條明細記錄

     

    場景描述:一個會員編輯頁面要指定該會員所在的省份、城市、地區,要求在選擇省份后會自動過濾該省份的城市,地區以此類推。

           以下所有步驟只是修改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的具體類相對應;必須要指定lookupGrouplookupName

    <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加入過濾項,例如在城市加一個省份的過濾項,在選擇省份時后,會通過回調方法將這個過濾項的值存到該過濾項中。這樣逐級過濾就實現了級聯下拉的效果.

    posted @ 2011-06-03 17:53 張昊 閱讀(2273) | 評論 (5)編輯 收藏

           大家可以簡單將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是通過中間過渡表來實現這種多對多的關系,例如一個項目可以有多個成員,而一個成員又有可能在多個項目中,建模的圖為

    posted @ 2011-05-31 10:34 張昊 閱讀(1102) | 評論 (0)編輯 收藏

    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,歡迎大家與他在技術上多多交流


    posted @ 2011-05-29 22:21 張昊 閱讀(879) | 評論 (0)編輯 收藏

    本文主要講解J-hi中樹的過濾。以員工部門樹為例。

    要求在點擊某個員工時,能夠查看到該員工所在的部門。

     

     

               1-部門樹

    下圖2是所有員工列表:

    -2

    當點擊王五時,顯示王五所在的部門結構樹如圖3

          -3

    主要代碼部分:

    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-docAPI

    而例子的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,歡迎大家與他在技術上多多交流


    posted @ 2011-05-19 22:04 張昊 閱讀(847) | 評論 (0)編輯 收藏

    樹形菜單能很好的呈現菜單項之前的從屬關系,結構清晰明了。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的頁面,點擊父節點的帶回按鈕即可看到效果,同樣lookupxzqhwz字段的地方也修改Edit.jsp頁面的onclick動作就行啦。



    該文檔是對J-Hi樹形的入門級介紹,J-Hi的樹功能還有:節點的過濾,lazy加載,一個節點可以多個圖標、復選框效果,多個實體組合形成一棵樹,我們將在以后繼續講解


                                         注:該文檔由J-Hi愛好者"馮思豪"提供,他的QQ號為382600911,歡迎大家與他在技術上多多交流

    posted @ 2011-05-12 00:58 張昊 閱讀(992) | 評論 (0)編輯 收藏

        J-Hi平臺在考慮到開發時與發布后對信息、安全、效率等方面的要求不同,從而提供了設置開發模式與發布模式的開關。這個開關配置在src下的hiFrameworkConfig.properties文件中。
    hi.depolyment.published=true
        下面讓我們就這個開關項做如下分析,如果值為true,也就是發布模式,它到底會影響哪些東西:

    信息內容
       1)菜單中“權限”、“權限資源”將不在顯示,因為一旦將做好的項目發布后,這些信息是不能讓客戶維護的。
       2)菜單中“觸發器”、“消息管理”將不可見,因為一旦定時服務設定好,一般來說客戶很少會調整,即使是調整也應該是由開發人員來調整觸發的周期與頻率。對于消息管理也是一樣。
       3) 整個“國際化”菜單項全部不顯示,這其中包括“多語言參數”、“語言編碼”、“時區”,原因這些內部均應該在開發過程中將信息內容一并編輯完成。比如有一個語言編碼就要有一套多語言參數與之對應,因些一旦系統上線,所有國際化部分的維護功能也應該同時完成。
       4)“應用配置”列表中,“刪除”圖標將不再顯示,因為如果系統上線,系統中的一些基礎配置項是不能刪除,而只能更改的

    對于這個功能的控制,是在main.jsp中,加入一個變量,代碼如下
    <%// 是否已發布的開關,其目的是如果為true則關閉那些對終端用戶不可見的功能按鈕 %>
    <ws:set name="published" value="@org.hi.framework.HiConfigHolder@getPublished()" />
    建議大家以后在自己采用J-Hi開發的系統中也可以采用該方式來控制頁面,這樣就可以做到即不影響開發,而在項目提交給用戶時同樣保證某些只在開發時才能用到的按鈕或功能,只要改變一個開關就可以控制。 

    安全
       如果采用了發布模式后,頁面提交的URL將會被加密,而開發模式URL則是以明文顯示,開關則試前后URL的效果如下:
    http://localhost:8080/hiUserEdit.action?hiUser.id=1
    http://localhost:8080/hiUserEdit.action?cf4a9619dd97fc2689fb63048237404f
       由此可以看出URL問號后的參數部分全部通過了加密處理,這樣使您做出的系統更安全,通過使別人URL分析不出你要獲取的信息參與也推導不出系統的結構

    效率
       1)如果是發布模式,DWZ版的所有js文件將采用壓縮的文件,而非一個一個的離散文件,這樣系統的傳輸的內容會更少,具體的方式參見styles.jsp文件
       2)如果是發布模式,系統在啟動時一次性加載枚舉實體枚舉值多語言參數應用配置這些常量性的信息進入緩存,在取這些信息時系統會自動從緩沖中取而并非每都要查詢數據庫。舉例來說,性別是一個下拉的枚舉,如果是發布模式只直接從緩沖區中取數據,而如果是開發模式它就會去數據庫中取數據,如果是一個人員列表,那么有幾個要顯示枚舉的地方就要去數據庫取幾次。因此開發模式的運行效率要遠遠低于發布模式,但開發模式更有實效性,只要數據有任何變化都可以實體的反應出來,即使是在同一個事務中,而發布模式只能在一個事務完成之后再能做數據同步處理(即內存與數據庫之間的數據同步)
    posted @ 2011-05-08 22:12 張昊 閱讀(720) | 評論 (0)編輯 收藏


    J-HiDWZ兩個國內優秀的開源項目強強聯合,攜手推出J-Hi4DWZ版。

     

     

    登錄頁面

    首頁面

    J-Hi生成器生成的編輯頁面:使你不用寫任何一行代碼就能實現富文本編輯、頁面校驗、上傳附件、自動帶回、主從表編輯等功能

     

    角色分派頁面:可以看到平臺提供左側樹型結構(無需任何編碼,簡單配置即可)


    當然樹還可以做成是彈出帶回值效果

     

     

    更新日志:

    1、融合DWZ富客戶端做前端頁面展示

    2、支持跨瀏覽器包括IE6\7\8\9 FireFox

    3、實現webworkstruts2無配置文件解決方案

    4、插件增加懸浮聯機幫助

    5、支持實體復制

     

    1、解決登錄用戶的信息與數據庫信息不一致的問題

    2、解決多語言標簽緩存問題

    3、生成時如果有從表不在菜單顯示

    4、解決在struts下角色、權限、人員會有垃圾數據問題

    5、增加二個對菜單樹的過濾的接口,及回調實現

    6、修改了對菜單樹非整數型的配置方法

    7、解決加刪除標識符的實體未做過濾的問題

    8、優化了webworkstruts的基類BaseAction

     

    開發人員列表:

    人員

    主要工作

    張慧華

    dwz集成,富客戶端開發

    楊新峰

    Eclipse插件開發

    張昊

    生成器及底層開發

    肖金華、尹福泉

    修改平臺功能頁面,修改bug

    測試人員列表:

         羅天文、伏占才、宋藝、肖金華、張昊

     

    下載地址:http://code.google.com/p/j-hi/downloads/list

    J-Hihttp://code.google.com/p/j-hi/

    DWZhttp://code.google.com/p/dwz/

     

    線上交流:133176937(滿),133177634(滿),133178083,134232577

     

    相關文章寫在J-Hi for DWZ版發布的前夜

                    J-Hi快速開發平臺到底快速在哪里?

                    “J-Hi”Java開源平臺的生力軍

     

    下一步計劃:

    1)  融合SpringJDBC

    2)  支持實體從數據庫反向導入并生成代碼

    3)  支持樹形組件的可視化配置

     

    posted @ 2011-05-04 15:18 張昊 閱讀(3438) | 評論 (7)編輯 收藏

    1、快速上手,降低學習曲線

           對于剛剛接觸J-Hi的人來說,它上手很容易,我們為每一個功能點都提供了懸浮幫助功能,即使沒有任何資料(當然我們已提供了視頻與開發文檔),您也可以通過向導與幫助在十分鐘之內就可以創建出您自己的項目原型。

           其次J-Hi平臺采用的大都是大家耳熟能詳的主流框架與技術,如果您對主流的框架有所了解,那么對J-Hi的學習就沒有任何阻力了。

    2、快速搭建開發環境

           也許您因為項目或自身開發團隊的不同會采用不同的框架技術,例如您團隊中對struts2熟悉的人遠遠要比掌握webwork的工程師要多,或者在您的項目中統計分析的功能很多,您要考慮ORM的效率問題,而不得不放棄hibernate而采用ibatisspringJDBC,也許您還要考慮數據庫問題等等。在搭建開發環境您一定會考慮很多因素,盡管搭建開發環境并不復雜,但還是不夠自動化,還要手動的配置,費時費力。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的關系,而類無論是POJODAOService都繼承自部門相應類作為父類,同時在JSP頁面上也會繼承所有部門的所有元素,這樣就形成了實體繼承關系,這就好比設計模式中最基本的“開閉原則”,對于所有的新生功能是開放的,而對于已有的老功能是關閉的,可以完全把老的功能視為一個黑箱。這樣即能保證已有功能的穩定性,又能加入新的功能做為補充。

    posted @ 2011-05-02 00:32 張昊 閱讀(6497) | 評論 (8)編輯 收藏

    實現方式
    1、在struts.xml或xwork.xml加如下配置信息
            <global-results>
                
                
    <result name="auto">/${proxy.config.packageName}/${proxy.method}.jsp</result>           
            
    </global-results>

    2、在BaseAction類中加入proxy的方法實現
          private ActionProxy proxy;
       
        public ActionProxy getProxy(){
            if(proxy  == null)
                proxy = ActionContext.getContext().getActionInvocation().getProxy();
            return proxy;
        }

    3、做一個JSP文件,文件名一定要與action的方法名相同,列如:a.jap那么action的方法的寫法
        public String a() throws Exception{
            
            
    return AUTO;
        }

    4、在某個Jsp頁面中調于這個無配置actoin的寫法
        actionName!a.action

    分析
       ActionProxy類是struts2或webwork提供的一個action代理類,它的作用是它的作用是記錄當前這個action的對象、action的名稱、配置信息及該action所屬的包名等信息。該接口的聲明如下
    public interface ActionProxy {

        
    /**
         * 
    @return the Action instance for this Proxy
         
    */
        Object getAction();

        
    /**
         * 
    @return the alias name this ActionProxy is mapped to
         
    */
        String getActionName();

        
    /**
         * 
    @return the ActionConfig this ActionProxy is built from
         
    */
        ActionConfig getConfig();

        
    /**
         * Sets whether this ActionProxy should also execute the Result after executing the Action
         *
         * 
    @param executeResult
         
    */
        
    void setExecuteResult(boolean executeResult);

        
    /**
         * 
    @return the status of whether the ActionProxy is set to execute the Result after the Action is executed
         
    */
        
    boolean getExecuteResult();

        
    /**
         * 
    @return the ActionInvocation associated with this ActionProxy
         
    */
        ActionInvocation getInvocation();

        
    /**
         * 
    @return the namespace the ActionConfig for this ActionProxy is mapped to
         
    */
        String getNamespace();

        
    /**
         * Execute this ActionProxy. This will set the ActionContext from the ActionInvocation into the ActionContext
         * ThreadLocal before invoking the ActionInvocation, then set the old ActionContext back into the ThreadLocal.
         *
         * 
    @return the result code returned from executing the ActionInvocation
         * 
    @throws Exception
         * 
    @see ActionInvocation
         
    */
        String execute() 
    throws Exception;

        
    /**
         * Sets the method to execute for the action invocation. If no method is specified, the method provided by
         * in the action's configuration will be used.
         *
         * 
    @param method the string name of the method to invoke
         
    */
        
    void setMethod(String method);

        
    /**
         * Returns the method to execute, or null if no method has been specified (meaning "execute" will be invoked)
         
    */
        String getMethod();
    }
     
       J-Hi借用了這個代理類,在action的基類也就是BaseAction中添加了對該類實例的引用,從而實體全局配置
           <result name="auto">/${proxy.config.packageName}/${proxy.method}.jsp</result> 
       其中${proxy.config.packageName}用來指定當前action所屬的包名,例如,"testjs"就是配置文件的包名
    <xwork>
        
    <package name="testjs" extends="hi" >
          
    <action name="materialList"
                class
    ="org.hi.testjs.action.webwork.MaterialListAction">
                
    <result name="success">/testjs/MaterialList.jsp</result>
                
    <interceptor-ref name="modelParamsStack" />
            
    </action>
    .
    </xwork>
      ${proxy.method}是指調用該action的方法名
      name="auto" 是我們特意為這樣無配置的actoin起了一個特定的名字,也就是說 
          

        public String a() throws Exception{
           
    return "auto";     
            或
            
    return AUTO;
        }
      效果是一樣的
     
      我們特意將這段result的配置放在了
    <global-results>中原因是省去寫配置文件,只要是return "auto";就會調用這個結果。那么它的結果是什么呢?對,是一個JSP,也就是說你通過actionName!method.action后,系統會自動執行這個方法,并自動調用這個aciton所屬包名下的與方法名相同的jsp文件。例如配置文件的包名為"testjs",actionName為"materialList",對應的class為"org.hi.testjs.action.webwork.MaterialListAction",你在這個action類中增加了一個a(),想通過調用該方法實現無配置調用jsp,那么你就應該將這個jsp文件放到web/testjs(與包名相同)目錄下,并且該jsp的文件名為a.jsp(與方法名相同)。調用這個action方法的寫法如下:materialList!a.action。OK,大工告成!!

    技巧
       為了適應不同人對action的開發習慣,J-Hi對struts2與webwork的生成方式是不同的。struts2是所有的操作都放在一個Action類中通過方法調用,而webwork是每個一操作一個Action類。兩種方式均有優勢也優有不足之處,大家在使用時全憑自己的習慣就好。我們之所以實現無配置,主要是考慮到J-Hi它不只是一個開發管理系統的平臺,也應該可以做網站或電子商務前端的開發。我們知道對于后臺管理系統主要考慮的是系統安全性(頁面的布局與樣式風格要統一),而網站或電子商務前端恰好相反,它追求的是安全不是問題因為它歡迎更多的瀏覽者不需要對每個操作都做權限控制(頁面的風格也五花八門,炫、酷不規則是這類系統的特點)。因此提供了無配置文件的方式,以滿足這類需求(當然純頁面還是要由美工來完成,無規則平臺的生成器是無法勝任該工作的)。由此而帶來的另一個問題是,平臺已經生成了很多aciton的功能,如何讓前臺與后臺共用這些已生成的action類呢?下面我們以struts2為例
       在BaseAction中有一個protected String returnCommand()方法,該方法是確定返回的結果的名字
        protected String returnCommand(String message){
            String viewMode 
    = HiConfigHolder.getViewMode();
            
            
    if(viewMode.equals("dwz")){                   
                
    if ((ajax == null || !ajax.trim().equals("1")) && message == null)
                    
    return SUCCESS;
                
    if(message == null)
                    
    return ajaxForwardSuccess(I18NUtil.getString("操作成功"));  //如果是dwz版就返回一個json對象的字符串
                
    else
                    
    return ajaxForwardError(message);
            }
            
            
    return SUCCESS;  //如果是經典版就返回success字符串
        }
      如果你想在前臺調用平臺已生成的action,而跳過權限控制,就可以通過無配置文件這種方式來實現,解決方案為,你在要做無配置的action類中覆蓋BaseAction的retunCommand()方法,覆蓋的實現方法如下:
        protected String returnCommand() {
            
            
    if(this.getRequest().getRequestURI().indexOf("!">0)   //如果在URL中包含!就說明是無配置的,它就會返回auto
                
    return "auto";
            
            
    return super.returnCommand();              //否則就走BaseAction也就是父類的retunCommand()方法
            }

      例如struts的action配置文件如下
    <struts>
        
    <package name="testjs" extends="hi" >
          
    <action name="material"
                
    class="org.hi.testjs.action.struts.MaterialAction">
                
    <interceptor-ref name="modelParamsStack" />
            
    </action>
    .
    </struts>
      平臺生成的MaterialAction類會有一個materialList(),你想在前臺調用而忽略權限,就可以寫成material!materialList.action,就可以了


    posted @ 2011-04-28 23:03 張昊 閱讀(1920) | 評論 (0)編輯 收藏

    安裝插件后的eclipse啟動不能創建hi項目 或者點完成時 很快就回到當前頁面。

    eclipse   創建 eclipse.exe 的快捷方式

    在快捷方式右鍵查看屬性 在目標后面加上 -clean 

    雙擊快捷方式啟動eclipse

    ok

    啟動tomcat時報錯

    把默認的刪除 

    新建服務器

    點完成 就ok



                                       注:該文檔由J-Hi愛好者"羅天文"提供,他的QQ號為610817750,歡迎大家與他在技術上多多交流

    posted @ 2011-04-27 01:29 張昊 閱讀(2849) | 評論 (7)編輯 收藏

    一、什么是代碼高手?你怎么證明自己是代碼高手?

    知道許多代碼技巧、JS炫彩技巧的人大有人在。你知道多少個.net函數,這一點都沒有意義。你知道多少個新鮮IT名詞,多少技術介紹,這也沒有意義。做,真正做一個原型,做一個項目,解決你手頭棘手的問題,這才有意義。

    1、快速準確的理解別人說的-〉

    2、快速的開發,還準確的反映了別人的需求-〉

    3、穩定,最少出BUG-〉

    4、高性能,10萬條記錄你能頂住,1000萬條記錄你能頂住嗎?這就是技術功底的考驗

    5、這還不夠,你的代碼是否能讓別人快速的理解了

    6、你的代碼是否能比較容易的接受不同客戶的需求差異

    這都是處處要你的分析功底、架構功底、編碼功底。

    二、怎么煉成高手?

    1、閱讀優秀的開源源代碼。先找代碼量不大的。要徹底的閱讀,剖析清楚有多少個類,這些類的關系。為什么要設計這樣的類架構,為什么要這樣設計接口。這些思考相當有深度。

    2、根據你的需求,把開源源代碼進行修改。因為開源源代碼是渾然一體,你加的功能是否很好和現有代碼融合。這相當考驗功底。

    3、 讀書,誰發明的這個東西就讀誰的書。如想學 SQLSERVER,就一定要讀SQLSERVER開發經理或技術小組寫的書。別人寫的書都會有歧義。要讀透,反復閱讀它的設計原理。不要只學會使用。比 如說SQLSERVER,寫SQL和SP就是懂SQLSERVER?我們一定要明白到SQLSERVER的數據頁面是如何組織的,為什么要這樣組織,它是 怎樣被載入內存中,它又是怎樣回寫到物理設備上。我們要到這個深度。否則,你只能是知道個皮毛,平時看是高手,一到真正難關立馬歇菜。

    如果你學的技術還不能幫助你解決你目前手頭的問題,說明你還學的不到位。

    4、 找到你的師傅。一個人的成長,很難是自己一個人苦苦學習摸索修煉。這樣提升很慢。你如果想快速發展,你必須找到你在這家公司中的引路人。他可能是你的入職 指引人,也可能是別人。你一定要好好觀察,看中了就一定要積極聯系上他緊緊的跟隨著他,平時多請教多觀察他的思考方式做事方式。

    5、給 自己樹立一個信念:我要在X年中成為公司所有人公認的技術高手。我要在X年終成為中國軟件業一流的程序員。必須設立目標,而且時時刻刻為這個目標奮斗,堅 持每天閱讀、思考、開發、修改代碼達到13-16個小時以上。有一個故事講的就是每件事要想做專業必須要經過1萬個小時的反復練習才能成功。對,我說的就 是這個意思。不瘋魔不成活。



    一個成功的產品的誕生是多么的曲折與艱難,中間會經歷多少商業競爭機緣巧合,也會浮現多少獨當一面的代碼英雄。
    一個人有沒有可能成為軟件高手,他是有一種說不清的氣質的,你知道那就是程序員精神,他是與眾不同的,你能明顯感覺的到。

    作為我個人,在技術上我是一直關注數據架構層、Java架構層、前端架構、和大型Web應用與研發。在業務上,我一直關注電子商務、互聯網生活服務/互聯網營銷/互聯網客戶關系社區、Web前端技術。 最后一句話:

    美到極致是瘋狂。希望大家在平時工作中開發每一個產品時,都能暗下決心:It's My Baby!

    對,它就是你創造的孩子,你要用心去雕琢它呵護它。?


                                        全文轉至張慧華的博文URL:美到極致是瘋狂
    posted @ 2011-04-25 22:54 張昊 閱讀(18305) | 評論 (5)編輯 收藏

        明天J-Hi for DWZ bate版就要發布了,心里很激動,感觸良多......
    J-Hi在沒集成DWZ之前頁面端一直是它的軟肋,之所以沒有對富客戶端的支持原因有三
       1)我自身的原因,始終認為過多的引入ajax會降低開發速度,增大了使用者的學習曲線,增大了開發工作量
       2)團隊內部原因,J-Hi核心團隊成員對js與頁面美工技術能力還很簿弱
       3)我一直沒有找到中國人自已做的設計優秀,而又不影響開發人員針對JSP的開發習慣的開源架構做集成
    有一天一個朋友(張國勇)給我推薦了DWZ,簡單的分析了一下它的運行原理,我一下子就喜歡上了它,原因如下:
       1)它是國產的,盡管內核仍采用的是JQuery,但在使用時基本上可以脫離JQuery,也就是說你可以基本的認為JQuery是一個黑箱
       2)它足夠輕量,內核很小加上JQuery壓縮后只有160K左右
       3) 它尊重開發人員的開發習慣,js部分的處理全部交給DWZ,只要在html中指定相應的class就可以。也就是說除非業務必須否則開發人員根本不用寫js代碼
       4)頁面與局布是通過JSP渲染,而不象ext等其它的富客戶端框架純js實現,這樣更方便開發人員對頁面的控制

        后來通過網絡我認識了DWZ開發團隊核心成員張慧華,給我的第一印象他是待人謙和,不善言談的人。我到現在還清楚的記得我們第一次見面的情景,我在我們約好的公交車站等他,他抱著他的女兒來接我,心情平靜而又談吐隨意。本來這一切都很平常,然而通過后面的聊天,卻讓我對他,對他的心態與人格肅然起敬。
               我寒喧的問他“這是你女兒?”
               他說“是,這是我大女兒”
               我開玩笑的說“你真行,難不成來有一個小女兒?”
               他說“對”
               我說“你的小女兒在那里,我怎么沒看到呀?”
               他說“住院了”
               我對“孩子怎么了?得了什么病?”當時我就在想每個為人父母的,孩子病了都會很難過
               他說“小女兒得了白血病”
        我聽到這里,一下驚呆了,不自禁的看了他一眼,他還是那樣心態平和。如此的大事在我和他聊天過程,他始終沒有情緒上的變化,反而是我心情跟著他的談話起伏不定。當時我在想,如果這事放在我的身上,我早就象熱鍋上的螞蟻,焦躁不安了。這是怎樣一個人,怎樣的一個心態啊?如此淡定,達觀的人生態度,我還第一次見到,對他充滿敬意。
        隨著后來我們接觸的越來越多,我看到他正像他說的一樣“我盡我最大的能力去做我該做的事情,無論結果如何起碼問心無愧,不會后悔”--每周都往返于醫院、家里和公司之間,有時還要在醫院通宵的護理他的小女兒(因為要化療)--我看他真是辛苦,看著他這樣我都覺得疲憊,我想這種疲憊不只是肉體的也許心理的更大吧!然后我卻從來沒有聽到他的一句怨言,甚至是述苦的話。我也從未安慰過他,我想如此堅強的人我的安慰是多余的。
        后來他答應幫助我做J-Hi對DWZ的融合工作,在工作過程中我更是對他超強的精力與嫻熟的技術佩服不已,因為我負閑在家,所以每天都在凌晨兩點多睡覺九點多起床,因為我們總是在QQ上實時聯絡,而他每天都是凌晨一點才會休息,他的公司與家離的很遠,每天六點半就要起床,如此精力充沛的人我還真是頭一次見到。他是一個工作狂,對技術有狂熱的興趣。我自認為自己對技術是一個近乎偏執的狂人,而與他相比,看來我把自己高估了。
       
        明天J-Hi for DWZ bate版就要發布了,我對曾經幫助過我的人充滿感激,特別是張慧華這里面不只是感激更多是敬意。我很慶幸有一個團隊,有大家的幫助,更有象張慧華這樣的朋友!

    posted @ 2011-04-25 02:30 張昊 閱讀(4977) | 評論 (16)編輯 收藏

    Svn簡介

    Subversion簡稱svn是一個自由/開源的版本控制系統。也就是說,在Subversion管理下,文件和目錄可以超越時空。也就是Subversion允許你數據恢復到早期版本,或者是檢查數據修改的歷史。正因為如此,許多人將版本控制系統當作一種神奇的“時間機器”。

    Subversion的版本庫可以通過網絡訪問,從而使用戶可以在不同的電腦上進行操作。從某種程度上來說,允許用戶在各自的空間里修改和管理同一組數據可以促進團隊協作。因為修改不再是單線進行,開發速度會更快。此外,由于所有的工作都已版本化,也就不必擔心由于錯誤的更改而影響軟件質量如果出現不正確的更改,只要撤銷那一次更改操作即可。

    某些版本控制系統本身也是軟件配置管理(SCM)系統,這種系統經過精巧的設計,專門用來管理源代碼樹,并且具備許多與軟件開發有關的特性比如,對編程語言的支持,或者提供程序構建工具。不過Subversion并不是這樣的系統。它是一個通用系統,可以管理任何類型的文件集。對你來說,這些文件這可能是源程序而對別人,則可能是一個貨物清單或者是數字電影。

    一個典型的客戶/服務器系統:

    Subversion版本庫的特別之處在于,它會記錄每一次改變:每個文件的改變,甚至是目錄樹本身的改變,例如文件和目錄的添加、刪除和重新組織。

    一般情況下,客戶端從版本庫中獲取的數據是文件系統樹中的最新數據。但是客戶端也具備查看文件系統樹以前任何一個狀態的能力。舉個例子,客戶端有時會對一些歷史性問題感興趣,比如“上星期三時的目錄結構是什么樣的?”或者“誰最后一個修改了這個文件,都修改了什么?”這些都是版本控制系統的核心問題:設計用來記錄和跟蹤數據變化的系統。

    服務器端軟件安裝

    這里選擇用VisualSVN-Server-2.1.7.msi搭建svn版本庫服務器。

    下載地址:http://www.visualsvn.com/server/download/

    一直默認進行安裝:

    選擇:VisualSVN Server and management Console

    D:

    (Location:指的是軟件安裝的位置。Repositories:是需要svn控制的源碼存放的位置。端口保持默認:443)

    (Anthentication:身份驗證模式,這里注意,如果選用第二個User Windows authentication,可能需要域環境。我選用的第一個。)

    服務器配置運行

    新建用戶

    右擊左側的Users,選擇新建---User ,新建用戶

    D:

    新建repository(版本庫)

    選中 Repositories,在右側的空白區域,選擇新建---Repository,輸入名字e-test,這樣就創建了一個項目

    D:

    url是:https://sihao-PC/svn/e-test

    sihao-PC是我的電腦名,e-test是我的項目名。中間的svn是默認就有的,注意由于我沒有加入域,所以在客戶端獲取的時候要把電腦名換成它的ip地址

    賦予用戶權限

    右擊e-test,所有任務--Manage Security 或者properties

    新建的用戶添加進去并賦值權限,如下圖:

    D:

    這樣就完成了服務器所有內容。

    (參考文檔:http://hi.baidu.com/sygwin/blog/item/7f2f1217168f0d144a90a793.html)

    客戶端軟件介紹

    客戶端可以選擇TortoiseSVN-1.6.15.21042-win32-svn-1.6.16.msi

    下載地址:http://tortoisesvn.net/downloads.html

    也可以用eclipsesvn插件:Subclipse

    下載地址:http://subclipse.tigris.org/

    本文主要介紹用eclipse插件的配置與使用

    客戶端軟件Subclipse的安裝

    J-hi標準完全版本已經配置好了svn插件,如果沒有的話可以用以下方法安裝:

    Eclipse的使用者可以通過Eclipse的插件自動下載和更新功能來安裝這個插件,在Eclipse的菜單中選擇Help->Software Updates->Find and Install-> Search for new features to install ->New Remote SiteURL中就輸入http://subclipse.tigris.org/updateEclipse就會自已安裝上了。

    安裝完成后,在Eclipseplugins中就會多了5個包,命名為org.tigris.subversion.*的都應該是了。打開Eclipse,window->show view窗口中多了一個SVN文件夾,到此就證明svn插件成功的安裝上了。具體的使用方法,在EclipseHelp中有詳細的幫助Subclipse - Subversion Eclipse Plugin,教你一步一步的使用SVN的客戶端了。如果你對subversion想進行深入的了解,那么看看help中的Version Control with Subversion一定有所收獲。據觀察,這份文檔和sbuversion安裝文件中提供的官方文檔一樣,這里看起來就更舒服些了。

    客戶端配置

    打開svn視圖

    安裝完畢后即可打開svn視圖

    或者顯示視圖:

    更快捷的方式是在右上角,點擊svn視圖圖標:

    C:

    新建資源庫

    輸入url的地址,需要將計算機名轉換成ip地址

    選擇永久接受:

    輸入用戶名和密碼:

    如果一切正常即創建了一個資源庫:

    C:

    可以看到了服務器上的目錄結構。

    SVN服務的使用

    共享項目

    首先需要將現有的項目共享到服務器上:

    選擇svn,下一步:

    選擇建好的資源庫,也可以在這里建資源庫:

    設置文件夾名稱:

    點擊完成,及完成了項目的共享與版本庫連接。

    接下來即可寫入項目第一個版本。

    運行到98%的時候可能會停滯很長時間,耐心等候即可。

    數據提交

    這是可以看到小組菜單里的item已經有變化了。

    修改程序后,即可提交:

    可以看到對程序的改動已經被記錄并提示,是否更新到版本庫。

    點擊確定即可將本地數據提交到服務器版本庫。

    數據下載更新

    在小組中點擊更新即可將服務器版本庫中的版本下載到本地。

    每次開始工作之前從版本庫中下載更新,階段工作完成并測試無誤之后提交。會讓團隊的合作開發變得方便可控。

    參考資源:http://www.uml.org.cn/pzgl/200904106.asp

    刪除或更改項目的資源庫位置

    若要刪除svn服務的資源庫,需要先從項目中刪除svn信息,可在小組中刪除版本共享鏈接先:

    刪除版本共享鏈接

    刪除資源庫位置

    回到svn視圖中,廢棄位置:

    這樣就使開發的源程序斷開了與版本共享庫的鏈接,即退出了svn服務。

    更改資源庫位置只用新建資源庫并配置即可。

    Subclipse的卸載

    卸載的方法也很簡單,也是點擊 Help => Software Updates => Manage Configuration

    http://www.uml.org.cn/pzgl/images/11204a160-12.jpg

    按上圖操作就可以卸載了。


                                     注:該文檔由J-Hi愛好者"尋找本拉登"提供,他的QQ號為382600911,歡迎大家與他在技術上多多交流

    posted @ 2011-04-23 20:13 張昊 閱讀(2131) | 評論 (3)編輯 收藏

    最近在做J-Hi融合SpringJDBC時遇到一個棘手的問題,那就是在insert一條記錄時如何取回記錄主鍵值的?問題主要讓我糾結在對跨數據庫SpringJDBC的處理上,大家都知道象SQLServer或MyServer主鍵的值是以自增的方式,而象Oracle主建的值通過序列生成并通過insert將值直接插入到表中的。為此SpringJDBC提供了兩種機制,
        1、主鍵自增的解決方案
            KeyHolder keyHolder = new GeneratedKeyHolder(); 
            
    this.getJdbcTemplate().update(new PreparedStatementCreator(){

                
    public PreparedStatement createPreparedStatement(Connection con)
                        
    throws SQLException {
       
    PreparedStatement ps
    =con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
     
                    
    return ps;
                }
                
            }, keyHolder);
            
        
    return keyHolder.getKey().intValue();
    keyHolder 數據庫自增主鍵值的持有者,它監聽PreparedStatement的返回的值Statement.RETURN_GENERATED_KEYS獲取主鍵值,并存放在自己的池中(實際上是一個list)一般來說,一個keyHolder實例只綁定一個PreparedStatement的執行,當然最好也只是插入一條數據庫記錄,這樣才能保證池中只有一個主鍵值。
    當keyHolder獲得主鍵值后,您可以在任何時候通過訪問keyHolder對象得到這個主鍵值,也就是說只要它的生命期存在,這個主鍵的值就一直不會丟失。
    總結:1)、在執行
    PreparedStatement之前創建自增主鍵的持有者對象keyHolder
          2)、在創建
    PreparedStatement對象時一定要聲明返回主鍵值,列如con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS)
          3)、只要keyHolder的生命期存在,那么主鍵的值在任何時候與位置你都可以取得到

        2、檢索數據庫序列生成的主鍵的解決方案
            OracleSequenceMaxValueIncrementer incr = new OracleSequenceMaxValueIncrementer(dataSource, "SIMPLE_SEQUENCE");
            
    return incr.nextIntValue();
    象Oracle這樣的數據庫SpringJDBC的解決方案一目了解,通過給定數據源dataSource與序列名"SIMPLE_SEQUENCE"就可以這個序列的最大值。當然還可以通過這個類設計緩沖區大小通過setCacheSize方法,該方法可以一次性取出多個值以減少與數據庫的訪問次數(數據庫的交互是很耗時與耗費資源的)

    J-Hi的問題與解決方法
        因為J-Hi要實現跨數據庫跨多個ORM框架因此對于SpringJDBC這兩種方案必須要融合到一起,并且在總體設計上還要與其它的ORM框架(目前J-Hi已融合的ORM框架有hibernate、ibatis2、ibatis3)的接口聲明相兼容,因此在對SpringJDBC集成的總體設計上我借鑒了hibernate的方言思想,通過方言將SpringJDBC兩種方案融合在J-Hi之中以實現對不同類型數據庫主鍵管理的差異性。
            KeyHolder keyHolder = new GeneratedKeyHolder(); 
            
    this.getJdbcTemplate().update(new PreparedStatementCreator(){

                
    public PreparedStatement createPreparedStatement(Connection con)
                        
    throws SQLException {
      
    ISpringJDBCHiDialect dialect 
    = sessionFactory.getDialect();   
    PreparedStatement ps
    =con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
     
                        
    if(stepFlage == primaryKeyIndex && valueClass.getPropertyName().equals(primaryKeyName)){
                            Number _id 
    = dialect.getSelectKey(entity.getEntityName(), getJdbcTemplate().getDataSource());
                    
    return ps;
                }
                
            }, keyHolder);
            
            
    if(obj.getPrimarykey() == null)
                BeanUtil.setPropertyValue(obj, 
    "id", keyHolder.getKey().intValue());

    從原生的SQL語句上講Oracle在insert時要插入主鍵值,而SQLServer恰好相反必須不能插入主鍵的值,我在設計上就是抓住這一特性,再結合方言,實現了跨數據庫的SpringJDBC, dialect.getSelectKey()方法,對應不同的數據庫方言,如果是oracle就會生成主鍵的值,而如果是SQLServer這個方法不會返回任何值,代碼如下
    Oracle的方言方法:
        public Number getSelectKey(String entityName, DataSource dataSource) {
            OracleSequenceMaxValueIncrementer incr 
    = new OracleSequenceMaxValueIncrementer(dataSource, "HIBERNATE_SEQUENCE");
            
    return incr.nextIntValue();
        }
    SQLServer的方言方法:
        public Number getSelectKey(String entityName, DataSource dataSource) {
    //        自增主鍵不用實現該方法
            return null;
        }
    通過返回主鍵值是否為null,還判斷在拼寫sql時是否插入主鍵字段的值
    最后通過
            if(obj.getPrimarykey() == null)
                BeanUtil.setPropertyValue(obj, 
    "id", keyHolder.getKey().intValue());
    Pojo對象是否主鍵值(如果沒有就說明是自增型的如SQLServer,如果有就說明是序列生成的如Oracle),來將其賦值到POJO的屬性中.
    posted @ 2011-04-21 00:19 張昊 閱讀(1952) | 評論 (3)編輯 收藏

      因為目前很多企業用SpringJDBC框架做數據訪問層,通過調查應大家的要求目前我正在做將SpringJDBC融入J-Hi平臺的工作。
      在以前我還真沒對各數據庫的翻頁處理做深入的分析,只是膚淺的知道SQLServer用top,Oracle用rownum,MySQL用limit通過sql語句做分頁處理,我一直認為通過對應數據庫的這些關鍵字就可以獲取指定的數據條數,而這些數據是在數據庫端就可以一次完成的。例如只取滿足條件的第11-20這10條記錄,這樣ResultSet就會只有10條結果,而事實并非如此,主要就糾結在SQLServer上。
      通過做J-Hi對SpringJDBC融合的開發,我才知道實際上SQLServer2000并不能滿足我們這樣現實的需求,而只有到了SQLServer2005這個局面才有了改觀,下面讓我們對SQLServer的分頁處理做如下分析:

       SQLServer2000,由于它只提供了top關鍵字,而top的作用只是滿足條件的前多少條記錄,因此在處理翻頁時,它是將滿足條件的前多少條記錄一并取出,如每頁10條,翻到第二頁時的sql語句為
    select top 20 HI_Org.* from HI_Org HI_Org
       也就是說會把前20條記錄一次性丟給java形成20條記錄的結果集,而對我們來說因為是第二頁每頁10條,所就是說只要這20條記錄的后10條,前10條是沒有任何意義的垃圾數據,這樣的處理機制不但效率會大大降低,而且隨著頁數的增加,比如我們要翻到第1000頁,那在結果集中就要有10000條記錄,因此也造成了資源的浪費。大家由此會推算出來,越往后翻頁,性能就越低。這種性能的低下不只是無用數據量的增加,而且也造成了對這些無用的數據處理的時間損耗。

       搞笑的時,用了這么久的SQLServer卻昏然不知,等到SQLServer2005微軟才算時對此做了補充與修改,下面是SQLServer2005的SQL語句        

    WITH query AS (select ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMPas __hi_row_nr__, hi_org.* from hi_org hi_org) SELECT * FROM query WHERE __hi_row_nr__ BETWEEN 11 AND 20
       通過上面的語句我們可以看出SQLServer2005提供了ROW_NUMBER()方法[這個方法有點象oracle的rownum,也許微軟對于這個功能就是抄習的甲骨文也不一定,哈哈],以記錄結果集的行數,不過還是點惡心,如果用之個方法還必須進行排序處理,如果沒有order by作修飾這個方法還是無效的。

        通過上面的一個小功能的分析,我真是對微軟及SQLServer產品有些失望,如此的功能要事隔5年才完善它,而且完善的并無新意,更何況象這樣的功能就連mysql這種免費開源的產品都早已實現,而SQLServer還是商業運作,真不知微軟的SQLServer在某些方面上都不如開源的產品它是做何感想?
      


    posted @ 2011-04-17 21:30 張昊 閱讀(2381) | 評論 (3)編輯 收藏

    場景分析

    如果項目大量使用了ajax或者項目使用了類似extjs這種富客戶端框架的朋友們可能會經常碰到一個問題:我們如何為客戶端提供正確有效的數據?例如以下簡單需求:

    有一個界面,用于顯示用戶名、用戶所在公司名稱、用戶擁有的權限名稱,使用ajax去服務端獲取數據。

    我們有以下三個類:

    User:用戶類

    Company:公司類

    Role:角色類

    用戶類1:M角色,用戶類1:1公司。

    這里有一段測試代碼,調用了j-hiJSONObject API進行序列化:

    我們測試結果如下:

    {"user":{"mobile":null,"primarykey":null,"parentEntity":null,"class":class test.User,"dataSymbol":null,"username":"zhangsan","cascadeDirty":false,"roles":[{"rolename":"角色1","primarykey":null,"parentEntity":null,"class":class test.Role,"dataSymbol":null,"cascadeDirty":false,"dirty":false,"deletedFlag":false,"version":1},{"rolename":"角色2","primarykey":null,"parentEntity":null,"class":class test.Role,"dataSymbol":null,"cascadeDirty":false,"dirty":false,"deletedFlag":false,"version":1}],"dirty":false,"deletedFlag":false,"version":null,"company":null},"id":1}

    我們發現,將整個對象序列化了。尤其是company對象,客戶端只需要公司名,但結果是所有屬性都被序列化了。

    我們不需要序列化所有屬性,在新版本的J-Hi中,提供了新的方法,輸出我們需要的屬性,看如下例子:

    輸出結果如下:

    {"user":{"username":"zhangsan","roles":[{"rolename":"角色1"},{"rolename":"角色2"}],"company":{"companyName":"新浪"}},"id":1}

    完美達到我們的要求。

    在某些需求中,我們甚至可以從客戶端發起獲取數據的請求,動態的獲取我們需要的數據,比如我們發起一個請求:

    {

    'entity': 'xxxxx.user.User' ,

    'returnType':'JSON',

    'properties': 'username, company.companyName, roles.rolename'

    },

    請求獲取User類對象的以下屬性username,company.companyName,roles.rolename

    服務器端返回User類型對象,并序列化成JSON返回,返回以下幾個屬性username,company.companName.

    通過j-hi的新JSONObject API,我們可以很方便實現這樣的功能,為客戶端提供任意數據。甚至能實現萬能的服務器查詢API

    代碼分析:

           JSONObject類一個將多個java對象封裝成一個JSON字符串的工具類,每一個java(POJO)對象都是對象JSON字符串的一個屬性,可以通過addJSONObject(),為要轉換的JSON不斷加入新的java對象。

           缺省在創建JSONObject對象時,構建函數參數已經加了一個java對象,如果JSON可能會有多個java對象拼接而成,就可以通過addJSONObject()累加的方式實現。

        /**

         *添加一個待轉換的java對象,使其作為JSON字符串的一部分

         *@paramjsonPropertyName給定JSON的屬性名

         *@paramobj待轉換的java對象,這個java對象可以是基礎類型比如日期、字符串,也可以是POJO對象,或者是Collection集合類對象

         *@paramobjectProperties返回JSON字符串對應POJO的屬性名列表,屬性名與屬性名之間用逗號分隔,如果該java對象的某個元素是集合也可以支持即集合屬性名.集合元素對象屬性名

         *,例如HiUserPOJO"id,org.orgName,org.id",注意:如果該參數為空

         *則只轉換一級屬性,即它不會級聯的返回屬性的屬性值

         */

        publicvoid addJSONObject(String jsonPropertyName, Object obj, String objectProperties)

        /**

         *獲得封裝后的JSON對象

         *@return返回一個JSON對象的字符串

         */

        public String toString()

    目的與意義:

    1、 在一次客戶端的請求過程中,盡量的壓縮傳輸數據的傳輸量,從而降低帶寬,提高傳輸效率

    2、 提高瀏覽器的對JSON對象的解析速度,對于IE瀏覽器來說9以下的版本對JSON的解析速度都很差,這也是適應目前客戶現場情況解決實際問題的方法

    3、 一個清爽沒有數據冗余的JSON對象,更方便你在客戶端做數據控制,例如根據返回的JSON動態的顯示列表的列數



                                         注:該文檔由J-Hi愛好者"葉青"提供,他的QQ號為405986916,歡迎大家與他在技術上多多交流

    posted @ 2011-04-12 22:44 張昊 閱讀(1854) | 評論 (0)編輯 收藏

       由于對J-Hi新版(j-hi for dwz)的開發工作已進入尾聲,現在已經開始內部測試,預計4月底會對外發布。新版本的截圖如下



       因此我們正在為下一步的工作與下一步的平臺升級做準備工作,在平臺目前的版本中支持Struts2、Webwork、hibernate、ibatis2、ibatis3,我們計劃在下一升級版中融入SpringMVC與SpringJDBC框架,如果興趣參與我們的設計與開發的人員歡迎加入到我們的項目中來。
      
       要求:1、對SpringMVC或SpringJDBC的底層非常熟悉
             2、對J-Hi的底層運行原理有一定了解
             3、要有帶領一個小團隊的組織能力
             4、對中國的開源有興趣與激情,并能始終堅持下來

       工作內容:
             1、編寫相應框架與J-Hi集成的詳細設計文檔
             2、編寫開發計劃的Project
             3、組織開發人員按計劃開發
             4、組織測試工作


       聯系方式:
             郵箱:hao.zhang.hi@gmail.com
             QQ群:133178083
      
       參考:
            http://code.google.com/p/j-hi/


    posted @ 2011-04-09 16:01 張昊 閱讀(1702) | 評論 (2)編輯 收藏

     1 ## displayMenu is defined in WEB-INF/classes/globalMacros.vm
     2 #macro(digui)
     3     #set ($s_parent = $s_owner.parent)
     4     #set( $count = $s_parent.components.size() - 1)
     5     #if($s_parent.components.get($count) == $s_owner)
     6         </ul></li>
     7         #set ($s_owner = $s_owner.parent)
     8         #digui()
     9     #end
    10 #end
    11 
    12 #macro( menuItem $menu $level )
    13   ## set title
    14   #set ($title = $displayer.getMessage($menu.title))
    15   #if ($level == 0)
    16       <li> <a href="javascript:void(0)">${title}</a>
    17           <ul>
    18   #else
    19     <li>
    20     #if ($menu.components.size() > 0)
    21        #set ($numItems = $menu.components.size())
    22          <#if($menu.action)href="$!menu.action"#end #if($menu.jsFunctionName)onclick="$!menu.jsFunctionName" href="javascript:void(0)"#end target="#if($menu.target)$!menu.target#end">${title}</a>
    23       <ul>
    24     #else
    25             <#if($menu.define.checkbox) tname="hi_checkbox_common" tvalue="$!menu.checkbox"#end" #if($menu.action)href="$!menu.action"#end #if($menu.jsFunctionName)onclick="$!menu.jsFunctionName" href="javascript:void(0)"#end target="#if($menu.target)$!menu.target#end">${title}</a>
    26     #end
    27     #if($menu.components.size() == 0)
    28       </li>
    29       #end
    30       #if ($level != 0 && $velocityCount == $menu.parent.components.size() && $menu.components.size() == 0)
    31            #set ($s_owner = $menu)
    32         #digui()
    33     #end
    34   #end
    35 #end
    36 
    37  <script type="text/javascript">
    38 ${menu.define.javascript}
    39 #if($menu.define.checkbox)
    40     function selectedcb(button){
    41     var checkeds = jQuery(button).parent().find(".tree :checkbox").filter(":checked").filter("[name]");
    42     var ids = new Array();
    43     var texts = new Array();
    44     checkeds.each(function(i){
    45         var input = jQuery(this);
    46         ids[i] = input.val();
    47         texts[i] = input.attr("text");
    48     });
    49     var result = new Array();
    50     if(ids.length == 0)
    51         return result;
    52     result[0= ids;result[1= texts;
    53     return result;
    54 }
    55 #end
    56  </script>
    57 
    58 <div style=" float:left; display:block; margin:10px; overflow:auto; width:200px; height:300px; border:solid 1px #CCC; line-height:21px; background:#FFF;"> 
    59     <ul class="tree treeFolder collapse#if($menu.define.checkbox) treeCheck#end">
    60 #displayMenu($menu 0)
    61 </ul>
    62 #if($menu.define.checkbox)
    63 <input type='button' name='button1' value='帶回'  onclick='bringBackCheckBox(selectedcb(this))'/ >
    64 #end
    65 </div>
    66 
    67 
    68 
    posted @ 2011-04-09 00:21 張昊 閱讀(2714) | 評論 (0)編輯 收藏

    主站蜘蛛池模板: 亚洲欧洲国产成人综合在线观看 | 激情97综合亚洲色婷婷五| 免费看大美女大黄大色| 成人毛片手机版免费看| 野花高清在线电影观看免费视频 | 亚洲AV无码一区二区三区鸳鸯影院| 亚洲av专区无码观看精品天堂| 亚洲福利视频网站| 亚洲日韩乱码中文无码蜜桃| 亚洲自偷精品视频自拍| 亚洲短视频在线观看| 亚洲国产成人久久| 亚洲永久在线观看| 亚洲国产精品无码中文lv| 精品国产亚洲一区二区三区在线观看| 亚洲狠狠婷婷综合久久| 国产亚洲综合一区二区三区| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 黄床大片30分钟免费看| 未满十八私人高清免费影院| 亚洲av乱码一区二区三区香蕉| 亚洲成A人片在线播放器| 青青青亚洲精品国产| 有码人妻在线免费看片| 99精品全国免费观看视频..| 午夜免费福利片观看| 91嫩草国产在线观看免费| 午夜a级成人免费毛片| jlzzjlzz亚洲乱熟在线播放| 亚洲人成色777777在线观看| 精品日韩亚洲AV无码| 亚洲情A成黄在线观看动漫软件 | 亚洲精品国产第1页| 中文无码亚洲精品字幕| 羞羞视频免费网站入口| aa级女人大片喷水视频免费| 免费精品国自产拍在线播放| 三级网站在线免费观看| 97国产免费全部免费观看| 国产免费人成视频在线观看| 亚洲精品无码久久久久sm|