隨筆 - 25  文章 - 32  trackbacks - 0
          <2009年1月>
          28293031123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          常用鏈接

          留言簿(2)

          隨筆檔案

          文章分類

          文章檔案

          相冊

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜



          一個圖書管理系統中的兩個對象:Book(書籍),BookType(書籍類型)。Book和BookType之間是多對一關系。

          說到主從表的關聯關系,自然而然地想起的一種實現方式就是選擇框,比如在Book的編輯界面是使用一個類型的下拉選擇框,選擇一個類型,然后保存。于是就有下例代碼:
          <h:selectOneMenu id="type" value="#{bookHome.instance.bookType.typeId}">
                              
          <f:selectItems value="#{bookTypeList.typeSelectItems}" />
          </h:selectOneMenu>
          這段代碼的作者(我)原本的想法是讓這個下拉框與bookHome.instance里的bookType.typeId幫定。比如當前的book類型id是1,修改后將book類型的id改為2,更新到數據庫。但是很不幸。這段代碼并不能執行預期的行為,或者說它還附加了其他行為。即Seam已經覺察到了在這個book中的類型的一個屬性(主鍵值)已經改變了。于是,試圖更新這個類型。但是JPA的規范中是不允許更改主鍵的,這就引起了一個錯誤。不信可以試下哦,呵呵。(以上描述我已經盡可能說清楚我的想法,但可能還是不怎么清楚,希望大家看不懂的說說哪里看不懂,我好改正)。我想說的是,不要直接幫定到外鍵,而是現幫定到一個臨時變量,比如在bookHome中多寫一個變量:
          public class BookHome extends EntityHome<Book>{
          private Long typeId;
          //..getter setter
          }
          然后將下拉框邦定到這個變量上,比如:

          <h:selectOneMenu id="type" value="#{bookHome.typeId}">
                              
          <f:selectItems value="#{bookTypeList.typeSelectItems}" />
          </h:selectOneMenu>
          。然后在重載的persist或者update方法中寫上:
          BookType newType = getEntityManager().find(BookType.class, typeId);
          instance.setType(newType);
          return super.persist();
          就完成了。我叫它“轉移邦定”,呵呵

          Seam的解決方案:
          其實Seam有另一種解決方案。比如如果你是自動生成代碼的方式,在BookEdit.xhtml中就會看到這樣的代碼:
          <div class="association" id="bookTypeParent">
              
                  
          <h:outputText value="There is no bookType associated with this book." 
                             rendered
          ="#{bookHome.instance.bookType == null}"/>
                  
                  
          <rich:dataTable var="bookType" 
                             value
          ="#{bookHome.instance.bookType}" 
                          rendered
          ="#{bookHome.instance.bookType != null}"
                        rowClasses
          ="rvgRowOne,rvgRowTwo"
                                id
          ="bookTypeTable">
                      
          <h:column>
                          
          <f:facet name="header">typeId</f:facet>
                          #{bookType.typeId}
                      
          </h:column>
                      
          <h:column>
                          
          <f:facet name="header">bookType typeId</f:facet>
                          #{bookType.bookType.typeId}
                      
          </h:column>
                      
          <h:column>
                          
          <f:facet name="header">typeName</f:facet>
                          #{bookType.typeName}
                      
          </h:column>
                      
          <h:column>
                          
          <f:facet name="header">action</f:facet>
                          
          <s:link view="/BookType.xhtml" 
                                   id
          ="viewbookType" 
                                value
          ="View" 
                          propagation
          ="none">
                              
          <f:param name="bookTypeTypeId" 
                                     value
          ="#{bookType.typeId}"/>
                          
          </s:link>
                      
          </h:column>
                  
          </rich:dataTable>

                  
          <div class="actionButtons">
                      
          <s:button value="Select bookType"
                                 view
          ="/BookTypeList.xhtml">
                          
          <f:param name="from" value="BookEdit"/>
                      
          </s:button>
                  
          </div>
                  
              
          </div>
          點擊“Select bookType”頁面就自動跳轉到BookTypeList頁面,列出所有的類型,每個類型后面都有一個select連接,點擊這個連接就可選中這個類型。然后回到BookEdit.xhtml。很Seam很強大吧,呵呵。其實為何這樣能完成一個選擇都是在BookEdit.page.xml里配置的。配置大概如下:
             <begin-conversation join="true"/>
             
             
          <action execute="#{bookHome.wire}"/>
             
             
          <param name="bookFrom"/>
             
          <param name="bookBookId" value="#{bookHome.bookBookId}"/>
             
          <param name="bookTypeFrom"/>
             
          <param name="bookTypeTypeId" value="#{bookTypeHome.bookTypeTypeId}"/>
           <begin-conversation join="true"/>  :開始一個conversation(我暫稱之為“頁面流”),如果已存在,就加入。而不重新創建。
          <action execute="#{bookHome.wire}"/>  :一最重要的這個。如果沒有執行這個方法這段跳轉就沒有任何效果了。,先來看下這個方法是怎么寫的吧:

          public void wire() {
                  getInstance();
          //獲取instance,放在這里是為了加在instance
                  BookType bookType = bookTypeHome.getDefinedInstance();//獲取類型。
                  if (bookType != null) {//如果選擇的類型不為null
                      getInstance().setBookType(bookType);//設置書籍類型
                  }
              }

          那bookTypeHome從哪來的呢?天上掉下的?呵呵,當然不是。就在BookHome的上部分:
          @In(create = true)
              BookTypeHome bookTypeHome;

          前面我說過了。這個@In就是拿來做雙向注入的。bookTypeHome是要注入的組件名稱。
          其他的都是參數了,沒啥好解釋的。
          但為什么在BookTypeList頁面點select,怎么就會自動跳轉到BookEdit.xhtml呢?奧秘就在這段代碼里(BookTypeList.xhtml):
          <s:link view="/#{empty from ? 'BookType' : from}.xhtml" 
                             value
          ="Select" 
                                id
          ="bookType">
                          
          <f:param name="bookTypeTypeId" 
                                  value
          ="#{bookType.typeId}"/>
                      
          </s:link>
          從BookEdit里傳來一個from。
          <s:button value="Select bookType"
                                 view
          ="/BookTypeList.xhtml">
                          
          <f:param name="from" value="BookEdit"/>
                      
          </s:button>
          就告訴了BookTypeList,是從BookEdit里來的,點Select的時候就不要去其他地方了。直接回去。

          好了,今天到這,困了,上面講的不明白的歡迎email或qq聯系我。。


          posted on 2008-12-24 23:02 phyeas 閱讀(1079) 評論(4)  編輯  收藏 所屬分類: Seam項目實戰

          FeedBack:
          # re: Seam新手實戰(4):外鍵 2009-01-19 16:21 藍天飛翔
          不要那么懶啊~~你多寫一些,我們就多學一些。呵呵
          在此謝謝謝了···  回復  更多評論
            
          # re: Seam新手實戰(4):外鍵 2009-01-31 09:06 phyeas
          @藍天飛翔
          呵呵,最近事情比較多。。  回復  更多評論
            
          # re: Seam新手實戰(4):外鍵 2009-02-25 10:51 藍天飛翔
          第一次看時,好多不明白,今天我又回來仔細看了看,解決好多的凝問,再次感謝!希望有空多寫寫。  回復  更多評論
            
          # re: Seam新手實戰(4):外鍵[未登錄] 2011-07-02 11:58 s
          我是看著這長大的  回復  更多評論
            
          主站蜘蛛池模板: 蚌埠市| 察雅县| 黎城县| 巴南区| 亳州市| 东台市| 永昌县| 鄂州市| 铁力市| 巩义市| 六枝特区| 嵊泗县| 成都市| 永寿县| 庆城县| 页游| 沁水县| 东乡族自治县| 宜阳县| 铜鼓县| 信阳市| 天柱县| 海南省| 耒阳市| 准格尔旗| 龙泉市| 高邑县| 吉隆县| 思南县| 陆丰市| 辽阳市| 比如县| 大悟县| 牟定县| 双辽市| 利津县| 都江堰市| 抚宁县| 紫云| 泉州市| 嘉祥县|