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

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

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

    隨筆-10  評論-22  文章-1  trackbacks-0
      2009年10月16日
    Annotation是JavaSE5開始引入的,在Java的世界已是大行其道,各大開源框架Hibernate、Spring等都對它無縫集成,足見其份量了。。
    其實很早就出現在程序員的視野,只是關注的比較少:@Override、@SuppressWarnings("unchecked"),開始主要覺得沒什么用處,后來公司的框架用到它,感覺還不錯。。于是來一記:

    在網上搜Annotation的學習資料不是很多,還是用的人不多,比較經典的入門就是這個:實戰篇:設計自己的Annotation,很清楚,通俗易懂,這里我就不贅述了。然而僅僅是弄懂它是怎么回事,具體還是沒什么用處,這也是大多數開發人員的感覺。

    在現在的公司的經歷兩次框架升級,第一次沒有用到Annotation,xml配置文件大行其道:Action跳轉、Ibatis sqlmapper、Form表單(我們的表單都是從后臺生成的),整個項目xml眼花繚亂,每個模塊都有自己專屬的配置文件,然后集中到一起處理,而我們最痛苦的莫過于寫那大量重復的配置文件。

    后來公司接了個ERP的單子,技術總監馬上意識到框架該升級了,他技術很牛,我們公司的框架就是他一人寫的,兩周之后,新框架出爐,xml只保留三分之一:Action跳轉、Form表單都不再使用xml配置,而是Annotation橫空出世,給我的感覺:它就像一個救世主,讓我們的框架重生,它就是這次升級的最大亮點,只有sqlmapper依然保留,這無可厚非,因為它原本是ibatis封裝的,Action控制器既不是Struts1,Struts2,也不是Webwork,是總監自己封裝的Servlet,Form表單都由后臺生成js組件拋到前端,通過反編譯看到源碼,其實還是很基礎的,貼些代碼上來看下吧:

    1.Action請求部分:
        /**
         * 顯示新增頁面
         * author YuWenLin
         * date 2010-5-13 上午10:31:57
         * 
    @param data
         
    */
        @Action(
    "/add.shtml")
        @Permission(
    "client.ContractType.add")
        
    public void add(ActionData data){
            FormBuilder builder 
    = data.getService(FormBuilder.class);
            builder.append(Type.
    class);
            builder.setAction(
    "client/contract/type/add.do");
            data.put(
    "script", builder);
            
    //向頁面拋出cookie提示信息
            MessageUtil.putMessage(data);
            data.setResulter(
    "template");
            data.setPath(
    "client/contract/type/type.shtml");
        }
    可能大家看得不太明白(每個公司都有自己框架),沒有關系,就兩句:
    @Action("/add.shtml")
    它就是負責請求顯示新增的頁面,就這一句,不需要像我們以前的action.xml(類似Struts2的跳轉),干凈利索吧,當然底層后臺有處理,但是公共的,不需我們管,至于
    @Permission("client.ContractType.add")
    就是用來處理權限管理的,也是Annotation的使用,就這一句。就權限管理,后面我也會記述。。。

    2.再來看看@Action底層的定義:
    package org.plugbase.action;

    import java.lang.annotation.Annotation;

    public interface Action
        
    extends Annotation
    {

        
    public abstract String value();
    }
    說明下:extends Annotation跟 @interface是一樣的效果,只不過前者手動extends,后者自動的。
    怎么樣,很基礎吧,跟jdk源碼是一樣的。。。

    3.JavaBean生成表單:
        @Widget(value="TextBox")
        @Valider({
    "notempty","len(2,8)"})
        
    public void setName(String name) {
            
    this.name = name;
        }
    給setter方法加Annotation,@Widget是組件,@Valider是驗證
    意思就是給name字段生成TextBox組件,并做驗證處理,后臺有相應的公共js組件,驗證控件庫調用,我們所有的表單組件都是這樣生成的,說實話,這樣生成一個頁面真有點繁鎖,既要寫js,又要寫后臺,前端還要配,還真是有技術含量,呵呵。。。但是它保證一致性,所有表單組件,驗證控件,如TextBox我們只有一套,所有人都去調用這一套,不得再重造,因為它是框架。。。

    4.@Widget底層定義:
    import java.lang.annotation.Annotation;

    public interface Widget
        
    extends Annotation
    {

        
    public abstract String value();

        
    public abstract String defaultValue();

        
    public abstract String dataType();

        
    public abstract String dataSource();
    }
    @Valider類似,當然這些都只是定義、聲明,具體怎么用,這里就不貼了,畢竟是人家東西嘛

    怎么樣,看到這些,似乎覺得Annotation開始起作用了,其實我一直覺得,Annotation就是為xml所生,因為它們倆是死對頭,不管單一地用誰,都有缺陷,
    只有結合才是完善,正所謂,沒有最好,只有更好,合理就行。

    在這里我可能沒有貼出什么@Annotation技術含量的東西,但是我想要表達的是一種思想,一種框架的思想,并不是什么地方都能用到Annotation,一般的中小型項目根本沒必要用它,因為xml就搞定,所以用在需要用的地方,將它的能量發揮到最大。。。

    以上僅為一家之言,歡迎拍磚。。。

    posted @ 2010-08-10 16:47 獨孤行 閱讀(1712) | 評論 (1)編輯 收藏
         摘要: 在項目中使用ibatis有一段時間了,之前一直用jdbc、hibernate。自我感覺ibatis是介于jdbc和hibernate之間的非常實用的輕量級框架,相信用過的人都有同感吧。對搞java的來說,上手是非常快的,只要你具備sql基礎,再加一點ORM的思想,夏昕的《ibatis開發指南》是不錯的選擇。 今天項目搞完了,我就把所學的,以及在項目中用到拿來貼一番,也是對我個人技術的總結吧,怎樣...  閱讀全文
    posted @ 2010-04-01 11:35 獨孤行 閱讀(3354) | 評論 (0)編輯 收藏
    thickbox是jQuery的一個插件,其作用是彈出對話框、網頁框,使用戶體驗度更加愉悅,下面就來簡單介紹它的幾種用法。
    聲明一下:這只是個人的總結記載而已。
    準備工作:你需要三個文件:thickbox.js、thickbox.css、jquery.js,網上到處可下
    具體使用:
    第一步:將這三個文件引入到你要使用thickbox的頁面
    <script type="text/javascript" src="jquery.js"></script> 
        
    <script type="text/javascript" src="thickbox.js"></script>
        
    <link rel="stylesheet" href="thickbox.css" type="text/css" />
    第二步:一般簡單使用就是給<a>標簽和Button添加樣式:class=thickbox
    還有就是通過thickbox函數調用:如tb_init()、tb_show();見下文。
    幾種不同用法:
    1.點擊顯示圖片:
     <a href="001.jpg" class="thickbox"><img src="001.jpg"/></a>
    ok,就這樣搞定
    2.點擊按鈕或鏈接:
    <input alt="#TB_inline?height=300&width=400&inlineId=div1" title="shawnliu" class="thickbox" type="button" value="Show" />   
       
    <a href="#TB_inline?height=155&width=300&inlineId=div2&modal=true" class="thickbox">Show hidden modal content.</a>
       
       
    <div id="div1" style="display:none">
       
    <P>
         這是一個非模式對話框。
       
    </P>
       
    </div>

       
    <div id="div2" style="display:none">
       
    <P>
         這是一個模式對話框。
         
    <p style="TEXT-ALIGN: center"><INPUT id="Login" onclick="tb_remove()" type="submit" value="  Ok  " /></p>
       
    </P>
       
    </div>
    說明:給你要使用thickbox的<a>或button添加"#TB_inline?height=300&width=400&",#TB_inline是thickbox固定用法,height和width是顯示彈出對話框的大小參數,inlineId是你要顯示的標簽或組件,modal是模式與非模式的選擇,當然你還可以接很多你自定義的參數
    3.一般在項目中用得比較多的就是加載form的頁面,如添加,編輯在同一個list列表頁面,這時我們就可以將添加和編輯都做成thickbox形式,如下圖:

    怎樣做呢一樣的,給添加鏈接加thickbox樣式:
    <a href="add.shtml?width=300&height=250" class="thickbox">新增</a>
    前提是你得將要顯示的頁面(add.shtml)做好,然后指定你要顯示的大小
    編輯同樣是一樣:先將原信息提取出來,再讓用戶修改:

    代碼也一樣:
    <a href="edit.shtml?width=300&height=250&nid=item.nid" class="thickbox">編輯</a>
    4.能自己定位到需要用thickbox的元素,不使用樣式,可以用函數,如:
    <div id="PicList">
    <a href="Pic01.jpg"><img src="Pic01s.jpg" border="0"/></a>
    <a href="Pic02.jpg"><img src="Pic01s.jpg" border="0"/></a>
    </div>

    $(function() {
    tb_init(
    "#PicList a[img]");});
    5.通過ajax加載的頁面,thickbox樣式會失效,解決辦法:
    只要在AJAX載入HTML并更新到頁面后執行下以下代碼:
    tb_init('.thickbox');
    6.自定義函數調用:
    如點擊縮圖,要顯示大圖,縮略圖URL只不過在大圖URL的后綴前加了s:
    <div id="PicList">
    <img src="Pic01s.jpg" border="0"/>
    <img src="Pic01s.jpg" border="0"/>
    </div>

    $(function() {
    $(
    "#PicList img").click(function() {
    tb_show(
    "",this.src.substring(0,this.src.length-5)+'.jpg',false);
    });});
    另外,如果想用其它事件,還可以將click改成你想觸發thickbox的事件。
    下班勒,大概記錄到這,以后再加吧。。。


    posted @ 2010-03-26 17:47 獨孤行 閱讀(4643) | 評論 (2)編輯 收藏

    在域模型(實體域)中,關聯關系是類與類之間最普遍的關系。根據UML語言,關系是有方向的。下面以客戶(Customer)和訂單(Order)的關系為例,闡述一下ORM的中的一對多映射:
    我們知道,在關系數據庫中,只存在外鍵參照關系,而且總是由“many”方參照“one“方。
    1.建立多對一單向關聯——Order(many)--->Customer(one):
    -------------------------------Order.java--------------------------------

    pack mypack;
    import java.io.Serializable;
    public class Order implements Serializable{
       
    private int id;
       
    private String orderNumber;
       
    private Customer customer;
       
       
    //構造方法及set方法get方法
       
    }
    在以上代碼中customer屬性要使用<many-to-one>來映射:
    多對一單向關聯(many方)
    <many-to-one>
        name 
    = "customer"   --待映射的持久化類屬性名
        column 
    = "customer_Id"  --數據庫外鍵字段
        
    class = "mypack.Customer"  --持久化類
        not
    -null = "true"/>
    a.  <many-to-one>的not-null屬性 
    not-null屬性會影響Hiberntae的運行時行為,Hibernate在保存Order對象時,會先檢查它的customer屬性是否為null:
    若為null:在執行session.save(Order)時會拋出PropertyValueException異常;
    原因很簡單:既然Customer為null,那么對應的外鍵Customer_Id也為null,試問外鍵都沒有,Order表的數據能插得進去嗎
    若將not-null 屬性設為false:表示外鍵引用可以為null,試想一下,數據庫數據可以插進去嗎?
    我們來看:在執行session.save(Order)時,發出了sql語句:insert into......
    但是當Hibernate自動清理(flush)緩存時,拋出新的異常:TransientObjectException
    所謂清理是提交事務或手動Flush,將session與數據庫保持同步,很顯然不可能同步嘛,Order對象雖然持久化,但Customer沒有.
        注:是否應該把<many-to-one>的not-null屬性設為true,這根據實際業務而定。通常,訂單總是由客戶自己發出,因此建議設為true.
    b.  級聯保存與更新
    默認情況下,Hibernate持久化一個對象,不會自動持久化所關聯的其它臨時對象,因此會有TransientObjectException,
    想它關聯也可以,<many-to-one>中加個屬性cascade="save-update"即可.

    2.建立一對多關聯——Customer(one)--->Order(many):
    -----------------------------Customer.java-------------------------------
    package mypack;
    import 
    public calss Customer implements Serlizliab;e{
        
    private int id;
        
    private String name;
        
    private Set orders = new HsahSet();

        
    //構造方法及set方法get方法
    }
    一對多關聯(one方)
    <set 
          name 
    = "orders"  --持久化對象的屬性
          cascade 
    = "save-update" --級聯操作
          
    <key cloumn = "customer_Id"/> --外鍵
          
    <one-to-many class = "mypack.Order"/> --持久化類
    </set>
    a.  <set>元素的inverse屬性
      在映射一對多的雙向關聯時,應該在“one”方把inverse屬性設為true,這樣可提高應用性能。
                        inverse:控制反轉,為true表示反轉,由它方負責;反之,不反轉,自己負責;
                        如果不設,one和many兩方都要負責控制,因此,會引發重復的sql語句以及重復添加數據,
            在建立兩個象的雙向關系時,應該同時修改關聯兩端的對象屬性:
                        customer.getOrders().add(order);
                        order.setCustomer(customer);

            這樣做可提高業務邏輯的獨立性,使業務邏輯的程序代碼不受Hibernate實現的影響。同理解除雙向關系也一樣。
    b.  級聯刪除(從數據庫刪除相關表記錄)
             當刪除Customer對象時,及聯刪除Order對象.只需將cascad屬性設為delete即可.
              注:刪除后的對象,依然存在于內存中,只不過由持久化態變為臨時態.
    c.  父子關系(邏輯刪除,只是解除了關聯關系)
             自動刪除不再和Customer對象關聯的Order對象.只需將cascade屬性設為delete-orphan.
                         customer.getOrders().remove(order);
                         order.setCustomer(null);
              注:當關聯雙方都存在父子關系,就可以把父方的cascade屬性設為delete-orphan,所謂父子關系,是由父方來控制子方的生命周期.
                         
           


    posted @ 2009-10-16 00:29 獨孤行 閱讀(3345) | 評論 (2)編輯 收藏
    主站蜘蛛池模板: 免费福利电影在线观看| 国产精品免费大片一区二区| 91精品啪在线观看国产线免费| 2048亚洲精品国产| 本道天堂成在人线av无码免费| 亚洲精品成人网久久久久久| 国产亚洲男人的天堂在线观看| 日韩一区二区在线免费观看| 亚洲AV无码国产剧情| 国产一区二区免费在线| 污网站免费在线观看| 久久久久国产成人精品亚洲午夜 | 久久不见久久见免费影院| 亚洲香蕉久久一区二区 | 亚洲精品无码专区久久同性男| 青青视频免费在线| 亚洲中文字幕无码永久在线 | 国产大片免费天天看| 亚洲AV无码国产精品色午友在线| 无码人妻一区二区三区免费看| 亚洲欧洲日产韩国在线| 无码免费午夜福利片在线| 国内成人精品亚洲日本语音| 亚洲国产精品尤物YW在线观看| 国产线视频精品免费观看视频| 亚洲av色福利天堂| 亚洲欧洲免费无码| 在线播放免费人成视频网站| 亚洲国产精品无码AAA片| 男女免费观看在线爽爽爽视频| 亚洲AV日韩AV一区二区三曲| 亚洲人成国产精品无码| 一区二区三区在线免费看| 美女视频黄免费亚洲| 国产gv天堂亚洲国产gv刚刚碰| 国产成人精品免费久久久久| 亚洲一级特黄特黄的大片| 亚洲Av无码国产情品久久| 99视频免费观看| 美女视频黄频a免费观看| 久久综合九九亚洲一区|