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

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

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

    posts - 66,  comments - 11,  trackbacks - 0
    EJB技術有賴于2種重要技術的存在:Java RMI-IIOP和JNDI.EJB客戶僅僅同其暴露的單一接口進行交互。其中暴露的接口

    和企業Bean本身必須遵循EJB規范。EJB規范要求企業Bean暴露若干所要求的方法,而這些暴露的方法是供EJB容器統一管理他

    們使用的,無論EJB組件部署在何種EJB容器中。
        EJB2.1規范定義了3種EJB組件類型。
      會話Bean:會話Bean用于建模業務過程。即為完成某些任務而存在。
      實體Bean:實體Bean用于建模業務數據。他們是數據對象。實體Bean是用于緩存數據庫信息的Java對象。
      消息驅動Bean:MDB類似于會話Bean,因為它們都是為完成某些任務而存在的。

        EJB組件是基于分布式對象構建的,遠程系統能夠調用分布式對象。當然,進程內的客戶、進程外的客戶及網絡中的其他

    客戶都能夠與分布式對象進行交互。具體過程如下:
        客戶調用存根:即為客戶端提供的代理對象。存根負責將網絡通信屏蔽掉,這對于客戶而言意義深遠。存根能夠使用

    Socket訪問網絡中的其他資源,其間將調用所需的參數構建成網絡要求的調用格式。
        借助于網絡:存根能夠實現與服務器端的骨架進行交互。骨架是為服務器端提供的代理對象。骨架負責將網絡通信屏蔽

    掉,這對于分布式對象而言意義深遠。骨架能夠處理來自Socket的訪問請求。當然,骨架還能夠將存根構建好的參數轉換成

    Java表示。
        骨架將具體的客戶調用委派給合適的分布式對象實現。因此,該對象將完成具體的訪問請求,并將結果返回給骨架。依

    此類推,骨架將結果返回給存根,最后客戶將獲得分布式對象的響應結果(通過存根獲得)。
        重要:存根和服務器端實現的對象都實現了同一接口(稱之為遠程接口)。其意味著存根克隆了分布式對象的方法簽名。

    調用存根中的方法的客戶以為其自身直接調用了分布式對象,但實際情況是客戶直接調用存根,而存根處理具體的網絡訪問

    工作。因此,這可以稱之為分布透明性。
        分布式對象是對如下幾個協作對象的一種抽象:存根、骨架、實現的對象,單一的參與者不可能構成分布式對象。
        分布式對象是很誘人的,因為開發者能夠基于網絡構建應用。在開發大型的分布式對象應用的時候,需要借助于中間件

    服務,如事務和安全性。
       
        遠程對象:
        (1)、企業Bean的業務邏輯需要在Bean類中實現。EJB規范定義了企業Bean類待實現的若干接口。這些接口使得所有的企

    業Bean類能夠暴露同一套接口。各種企業Bean的Bean類都需要實現javax.ejb.EnterpriseBean接口。
        當然,EJB規范分別為會話Bean、實體Bean和消息驅動Bean提供了更專屬的接口類型,

    SessionBean,EntityBean,MessageDriverBean.
        (2)、當客戶使用企業Bean類的某實例時,它并不是直接調用Bean類的方法,EJB容器將攔截客戶調用,然后委派給企業

    Bean實例。通過攔截客戶請求,EJB容器能夠自動操作隱式中間件服務。
        因此,在客戶和EJB組件間,引入了間接層,即EJB容器。引入的間接層將自身封裝為單一的網絡使能對象,即EJB對象,

    EJB對象正是請求攔截器。EJB對象是代理對象,它可以與網絡、事務、安全性等進行交互。企業Bean客戶調用EJB對象提供的

    方法,而不是企業Bean本身。因此,EJB對象必須復制企業Bean類暴露的業務方法。但是,自動生成EJB對象的工具是怎么知

    道業務方法的呢?答案是,通過企業Bean提供者提供的接口來實現,即遠程接口。這個接口復制企業Bean類暴露的業務方法。

    EJB容器負責管理EJB組件,通過調用EJB組件提供的回調方法,EJB容器能夠同EJB組件交互。這些回調方法僅供EJB容器管理

    EJB組件使用。
        EJB容器最為重要的一項工作是,提供EJB組件運行的環境。EJB容器宿主了EJB組件,從而供遠程客戶調用。因此,可以

    認為EJB容器充當了客戶和EJB組件的中間人。EJB容器負責將客戶連接到EJB組件,完成事務協調工作,提供持久化能力,管

    理EJB組件的聲明周期及其他任務。
        EJB的遠程接口還需復制企業Bean類的業務方法。一旦企業Bean客戶調用業務方法,EJB對象將把調用操作委派給相應的

    Bean類。
        (3)、Java RMI-IIOP和EJB對象:javax.ejb.EJBObject繼承于java.rmi.Remote.任何實現了Remote接口的對象都是遠程

    對象,即能夠從其他JVM中訪問到它,這就是Java實現RMI方式。由于容器提供的EJB對象實現了EJB組件的遠程接口,因此EJB

    對象也間接實現了java.rmi.Remote接口。EJB對象是具有完整網絡功能的RMI-IIOP對象,供其他JVM或者網絡中其他物理機器

    訪問。實際上,EJB遠程接口僅僅是RMI-IIOP遠程接口,只不過它還遵循EJB規范罷了。
        遠程接口還必須遵從RMI-IIOP的參數傳遞約定。并不是所有的內容都能夠跨越JVM傳遞的。方法中傳遞的參數必須是符合

    RMI-IIOP約定的有效Java類型,如Java原型、序列化對象和RMI-IIOP對象。
        總之,EJB容器需要負責權衡資源管理和管理已部署EJB組件的生命周期。
    posted @ 2009-10-28 15:39 王永慶 閱讀(267) | 評論 (0)編輯 收藏
        EJB組件技術吸收了企業級計算領域中各個方面的豐富經驗和知識,比如分布式計算、數據庫、安全性、組件驅動軟件等。服務器端開發平臺,即Java2平臺企業版,企業Bean組件架構是J2EE的重要部分。
        J2EE是對概念、編程標準、技術革新的統稱,即基于Java編程語言開發服務器端應用。借助于J2EE,開發者能夠快速構建分布式、擴展性強、可靠的、便攜性好、安全的服務器端應用。
        EJB,是基于Java的服務器端組件架構技術。在Java應用服務器提供商提供的分布式基礎框架(比如,J2EE應用服務器)的基礎之上,開發者能夠快速、輕松的構建服務器端組件。EJB的重要設計初衷是保證應用能夠在任一提供商提供的企業中間件服務上暢行無阻,而且其便攜性、可重用性都是一流的。
        分布式系統:通過將傳統的大型應用系統分解成多層系統,這使得組成應用系統的各層相互獨立,并且承擔的職責各不相同。早先,在整個中間件領域至少存在50個應用服務器。起初,各個應用服務器分別以非標準、專有的方式提供組件服務。因此,它們對于組件服務的認識各不相同,而且對具體提供組件服務的方式都不盡相同。更不用談組件同應用服務器的具體交互了。這樣的結果是:一旦組件部署到某個應用服務器,則它就被鎖定到該應用服務器上。這對于客戶而言,是不希望看到的情景。
        如果能夠在不同ISV間達成共識,比如在應用服務器和組件間提供相同的接口,供開發和部署應用使用,則這將使得任何組件能夠運行在任一應用服務器中。與此同時,組件也能夠在不同應用服務器間實現熱插拔,而且不用修改應用代碼,甚至也不用重新編譯組件本身。本書將這種共識稱之為組件架構。
        服務:就是一組提供具體業務操作功能的相關組件。SOA具有極強的獨立性,這些SOA提供的服務能夠同其他服務進行交互,而不管其實現方式和部署的目標平臺如何。因此,將這些獨立、松耦合的服務集成起來是很有現實意義的。
        SOAP:簡單對象訪問協議,SOAP是基于XML、應用級的協議,供分布式網絡中交換信息使用。目前,SOAP支持2種分布式計算模型:面向RPC和面向文檔風格的SOAP消息。
        Web服務為那些分布式、松耦合SOA應用場合提供了強有力的解決方案。借助于WSDL能夠描述WEB服務;借助于SOAP能夠訪問到WEB服務。
        EJB僅僅是J2EE的組成部分之一。其中,J2EE平臺規范是由JCP指定。J2EE平臺規范的使命是,提供平臺獨立的、便攜的、多用戶的、安全的、遵循標準的企業級平臺。而且,它必須基于java和在服務器端部署。
        
      
    posted @ 2009-10-27 22:52 王永慶 閱讀(193) | 評論 (0)編輯 收藏
    Blob、Clob字段的映射
         Blob和Clob字段的區別在于,Blob字段采用單字節存儲,適合保存二進制數據,如圖片文件。Clob字段采用多字節存儲,適合保存大型文本數據。
         在Oracle中Blob/Clob字段獨特的訪問方式,Oracle Blob/Clob字段本身擁有一個游標,JDBC必須必須通過游標對Blob/Clob字段進行操作,在Blob/Clob字段被創建之前,我們無法獲取其游標句柄,這也意味著,我們必須首先創建一個空Blob/Clob字段,再從這個空Blob/Clob字段獲取游標,寫入我們所期望保存的數據。

        實體粒度設計:
        在Hibernate世界里,我們經常聽到"fine-grained object model"直接翻譯就是適當的細粒度對象模型。
        適當的比較模糊,細粒度就是將原本業務模型中的對象加以細分,從而得到更加精細的對象模型。就是劃分出更多的對象。分為:面向設計的細粒度劃分和面向性能的細粒度劃分。
        對于單表的對象細分,在Hibernate中可借助Component節點的定義來完成。何謂Component?從名字上來看,既然稱之為組件,則其必然是從屬于某個整體的一個組成部分。在Hibernate語義中,我們將某個實體對象中的一個邏輯組成成為Component.Component與實體對象的根本差別,就在于Component沒有標示,它作為一個邏輯組成,完全從屬于實體對象。通過Component定義,我們將T_User表實際映射到了3個類,TUser,Contact和Name,這樣我們就可以在傳統關系型庫表上,實現了面向對象的領域劃分。
        面向性能的細粒度劃分:
        當我們通過Hibernate加載TUser對象時,Hibernate會從庫表中讀取所有的字段數據,并構造TUser實例返回。這里就產生了一個性能方面的問題,作為blob/clob等重量級字段類型,數據庫讀取操作代價較高。對于需要處理resume和image的應用邏輯而言,這樣的代價無法避免,而對于那些無需resume和image信息的操作而言,如此性能無謂的損耗實在可惜。
        如何避免這個問題,Hibernate3提供了屬性的延遲加載功能,通過這個功能,我們可以在調用TUser.getResume/getImage時才真正從數據庫中讀取數據。對于hibernate2來說我們通過繼承關系,我們將一個對象進行縱向細分來解決這個問題。我們通過在子類的映射文件中class節點指定polymorphism="explicit"聲明了一個顯示多態關系。聲明為顯示多態的類,只有在明確指定類名的時候才會返回此類實例。

      
    package com.wyq.hibernateLoad;

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.sql.Blob;
    import java.sql.Clob;
    import java.sql.SQLException;

    import org.hibernate.Hibernate;
    import org.hibernate.LockMode;
    import org.hibernate.Session;
    import org.hibernate.Transaction;

    import com.wyq.hibernate.TUser2;

    public class TUserOperator {
        Session session 
    = null;
        
    //復合主鍵加載數據
        public void loadData(){
            TUser2 user 
    = new TUser2();
            user.setFirstname(
    "Kevin");
            user.setLastname(
    "Shark");
            user 
    = (TUser2)session.load(TUser2.class, user);
            System.out.println(
    "User age is=>"+user.getAge());
        }
        
    //SQL保存圖片
        public void saveImage(){
            TUser2 user 
    = new TUser2();
            user.setAge(
    new Integer(20));
            
            
    try {
                FileInputStream imgis 
    = new FileInputStream("C:\\inimage.jpg");
                
                Blob img 
    = Hibernate.createBlob(imgis);
                user.setImage(img);
                
                Clob resume 
    = Hibernate.createClob("This is Clob");
                user.setResume(resume);
                
                Transaction tx 
    = session.beginTransaction();
                
                session.save(user);
                tx.commit();
                
            } 
    catch (FileNotFoundException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }
    catch (IOException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
    //SQL讀取圖片
        public void getImageObj(){
            TUser2 user 
    = (TUser2)session.load(TUser2.class,new Integer(3));
            Clob resume 
    = user.getResume();
            Blob img 
    = user.getImage();
            
            
    try {
                InputStream is 
    = img.getBinaryStream();
                
                FileOutputStream fos 
    = new FileOutputStream("c:\\outimage.jpg");
                
    byte[] buf = new byte[102400];
                
    int len;
                
    while((len=is.read(buf))!=-1){
                    fos.write(buf,
    0,len);
                } 
                fos.close();
                is.close();
                
            } 
    catch (SQLException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }
    catch (FileNotFoundException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }
    catch (IOException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
    //Oracle保存圖片
        public void saveForOracleImage(){
            TUser2 user 
    = new TUser2();
            user.setAge(
    new Integer(20));
            user.setImage(Hibernate.createBlob(
    new byte[1]));
            user.setResume(Hibernate.createClob(
    " "));//注意這里的參數是一個空格
            
            Transaction tx 
    = session.beginTransaction();
            
            session.save(user);
            
    //調用flush方法,強制Hibernate立即執行insert sql
            session.flush();
            
    //通過refresh方法,強制Hibernate執行select for update
            session.refresh(user, LockMode.UPGRADE);
            
            
    //向Blob寫入實際內容
            oracle.sql.BLOB blob = (oracle.sql.BLOB)user.getImage();
            
    try {
                OutputStream out 
    = blob.getBinaryOutputStream();
                
                FileInputStream imgis 
    = new FileInputStream("c:\\inimage.jpg");
                
    byte[] buf = new byte[10240];//10k緩存
                int len;
                
    while((len=imgis.read(buf))>0){
                    out.write(buf,
    0,len);
                }
                imgis.close();
                out.close();
                
                
    //向CLOB寫入實際內容
                oracle.sql.CLOB clob = (oracle.sql.CLOB)user.getResume();
                java.io.Writer writer 
    = clob.getCharacterOutputStream();
                writer.write(
    "this is my resume");
                writer.close();
                session.save(user);
                tx.commit();
            } 
    catch (SQLException e) {
                e.printStackTrace();
            }
    catch (FileNotFoundException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }
    catch (IOException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
        
    }


        實體層次設計:繼承關系是關系型數據與面向對象數據結構之間的主要差異之一。
        Hibernate中支持3種類型的繼承形式:
        1、表與子類之間的獨立一對一關系。
        2、每個子類對應一張子表,并與主類共享主表
        3、表與類的一對多關系



      
    posted @ 2009-10-27 22:32 王永慶 閱讀(227) | 評論 (0)編輯 收藏
       對于新系統的設計開發而言,我們應該盡量避免在哭表中引入與業務邏輯相關的主鍵關系。
        將業務邏輯主鍵引入庫表,將使得底層庫表結構與業務邏輯相耦合,之后業務邏輯的變化,將很可能對底層數據庫結構產生連帶影響。
        復合主鍵的引入,很大程度上意味著業務邏輯已經侵入到數據存儲邏輯之中。因此在新系統的設計過程中,我們應該盡量避免這樣的情況出現。
        Hibernate中,通過composite-id節點對復合主鍵進行定義。
        對于復合主鍵而言,我們可以通過2種方式確定主鍵:
        1>基于實體類屬性的復合主鍵
        復合主鍵由實體類中的屬性組成,此時,實體類本身即同事扮演復合主鍵類的角色。
       
    <hibernate-mapping>
        
    <class name="com.wyq.hibernate.TUser2" table="T_User2">
            
    <composite-id>
                
    <key-property name="lastname" column="lastname" type="string"/>
                
    <key-property name="firstname" column="firstname" type="string"/>
            
    </composite-id>
            
    <property name="age" column="age" type="integer">
            
    </property>
        
    </class>
    </hibernate-mapping>
        Hibernate要求復合主鍵類實現equals和hashcode方法,以作為不同數據之間識別的標志。
        主鍵類的加載:我們可以將TUser2類對象本身作為查詢條件進行檢索:
        2>基于主鍵類的復合主鍵
        我們可以將主鍵屬性獨立到一個單獨的類中。實現方法類似,只不過映射文件的composite-id節點要引入class和name屬性。
    posted @ 2009-10-27 22:30 王永慶 閱讀(147) | 評論 (0)編輯 收藏
        有一周的時間沒有更新技術了,最近離職(南京合榮欣業),交接的東西太多,最后還要完成一個場景(支付信息業務登記薄查詢)的開發,當初都不應該接這個場景,現在每天都在弄,還好昨天弄完了,明天可以繼續看書更新技術了,這3年一直在技術上追尋著,可能沒有學到新的技術,但是,感覺架構的思想理解了不少,每一種技術的出現都是有他的原因的,不一定是新的技術就要用,要選擇適合自己的。
        3年的時間,做IT的自己認識的朋友有限,不管男女(女的更少,能稱得上朋友的),很大程度上是自己的性格所限,沒辦法啊,老天爺給了這個性格,都說性格可以改變,那都是扯,俗話說得好,狗改不了吃屎,性格是天生的,除非后天遇到什么重大事件,否則很難改變。自己的這種沉默的性格,也有點好處,就是對程序來說,可能只關注代碼吧,但是也沒做到牛B的那種,是說技術大牛。
        討厭做程序的人,可能是太枯燥了,說到這里吧,下周開始繼續博客,希望這次能堅持住。

    posted @ 2009-10-24 14:13 王永慶 閱讀(140) | 評論 (0)編輯 收藏
    package com.wyq.hibernate;

    import java.io.Serializable;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Types;
    import java.util.ArrayList;
    import java.util.List;

    import org.hibernate.Hibernate;
    import org.hibernate.HibernateException;
    import org.hibernate.usertype.UserType;

    public class EMailList implements UserType {
        
        
    private List emails;
        
        
    private static final char SPLITTER = ';';
        
        
    private static final int[] TYPES = new int[]{Types.VARCHAR};

        
    public boolean isMutable() {
            
    return false;
        }
        
    public int[] sqlTypes() {
            
    return TYPES;
        }
        
    public Class returnedClass() {
            
    return List.class;
        }
        
    /**
         * 創建一個新的List實例,包含原有List實例中的所有元素。
         
    */
        
    public Object deepCopy(Object value) throws HibernateException {
            List sourcelist 
    = (List)value;
            List targetlist 
    = new ArrayList();
            targetlist.addAll(sourcelist);
            
    return targetlist;
        }
        
    /**
         * 判斷email list是否發生改變
         
    */
        
    public boolean equals(Object x, Object y) throws HibernateException {
            
    if(x == y)return true;
            
    if(x!=null && y!=null){
                List xList 
    = (List)x;
                List yList 
    = (List)y;
                
                
    if(xList.size() != yList.size())return false;
                
    for(int i=0;i<xList.size();i++){
                    String str1 
    = (String)xList.get(i);
                    String str2 
    = (String)yList.get(i);
                    
    if(!str1.equals(str2))return false;
                }
                
    return true;
            }
            
    return false;
        }
        
    /**
         * 從resultSet中取出email字段,并將其解析為List類型后返回
         
    */
        
    public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
            
    throws HibernateException, SQLException {
            String value 
    = (String)Hibernate.STRING.nullSafeGet(rs,names[0]);
            
    if(value!=null){
                
    return parse(value);
            }
    else{
                
    return null;
            }
        }
        
    /**
         * 將List型的email信息組成字符串后保存到email字段
         
    */
        
    public void nullSafeSet(PreparedStatement st, Object value, int index)
            
    throws HibernateException, SQLException {
            System.out.println(
    "Set method executed");
            
    if(value!=null){
                String str 
    = "";//assemble((List)value);
                Hibernate.STRING.nullSafeSet(st, str, index);
            }
    else{
                Hibernate.STRING.nullSafeSet(st, value, index);
            }
        }
        
    /**
         * 將String拼裝為一個字符串,以";"分隔
         
    */
        
    private String assemble(List emailList){
            StringBuffer strBuf 
    = new StringBuffer();
            
    for(int i=0;i<emailList.size()-1;i++){
                strBuf.append(emailList.get(i)).append(SPLITTER);
            }
            strBuf.append(emailList.get(emailList.size()
    -1));
            
    return strBuf.toString();
        }
        
    /**
         * 將以";"分隔的字符串解析為一個字符串數組
         
    */
        
    private List parse(String value){
            String[] strs 
    = org.apache.commons.lang.StringUtils.split(value,String.valueOf(SPLITTER));
            List emailList 
    = new ArrayList();
            
    for(int i=0;i<strs.length;i++){
                emailList.add(strs[i]);
            }
            
    return emailList;
        }
        
    public Object assemble(Serializable arg0, Object arg1)
                
    throws HibernateException {
            
    // TODO Auto-generated method stub
            return null;
        }

        

        
    public Serializable disassemble(Object arg0) throws HibernateException {
            
    // TODO Auto-generated method stub
            return null;
        }

        

        
    public int hashCode(Object arg0) throws HibernateException {
            
    // TODO Auto-generated method stub
            return 0;
        }
        
    public Object replace(Object arg0, Object arg1, Object arg2)
                
    throws HibernateException {
            
    // TODO Auto-generated method stub
            return null;
        }

        

    }

    posted @ 2009-10-16 16:57 王永慶 閱讀(162) | 評論 (0)編輯 收藏
        我們的目標是為數據邏輯層及業務邏輯層提供更加易于操作的對象,根據這里的情況,將email字段映射為一個List集合

    類型是個不錯的選擇,如何將一個字段映射為List類型,Hibernate并沒有提供原生支持,我們必須實現自己的UserType.
      
    package com.wyq.hibernate;

    public interface UserType {
        
    /**
         * 返回UserType所映射字段的SQL類型(java.sql.Types)
         * 返回類型為int[],其中包含了映射各字段的SQL類型代碼
         * (UserType可以映射到一個或者多個字段)
         * 
    @see java.sql.Types
         * 
    @return int[] the typecodes
         
    */
        
    public int[] sqlTypes();
        
    /**
         * UserType.nullSafeGet()所返回的自定義數據類型
         * 
    @return Class
         
    */
        
    public Class returnedClass();
        
    /**
         * 自定義數據類型的對比方法
         * 此方法將用作臟數據檢查,參數x,y分別為數據的2個副本
         * 如果equals方法返回false,則Hibernate將認為數據發生變化,并將變化更新到庫表中
         
    */
        
    public boolean equals(Object x,Object y)throws HiberanteException;
        
    /**
         * 從JDBC ResultSet讀出數據,將其轉換為自定義類型后返回
         * (此方法要求對可能出現的null值進行處理)
         * names中包含了當前自定義類型的映射字段名稱。
         
    */
        
    public Object nullSafeGet(ResultSet rs,String[] names,Object owner)throws HibernateException,SQLException;
        
    /**
         * 本方法將在Hibernate進行數據保存時被調用
         * 我們可以通過PreparedStatement將自定義數據寫入對應的庫表字段
         
    */
        
    public void nullSafeSet(PreparedStatement st,Object value,int index)throws HibernateException,SQLException;
        
    /**
         * 提供自定義類型的完全復制方法
         * 本方法將用作構造返回對象
         * 當nullSafeGet方法調用之后,我們獲得了自定義數據對象,在向用戶返回自定義數據之前,deepCopy方法將被調用,
         * 它將根據自定義數據對象構造一個完全拷貝,并將此拷貝返回給用戶使用。
         * 此時,我們就得到了自定義數據對象的2個版本,第一個是從數據庫讀出的原始版本,其二是我們通過deepCopy構造的
         * 復制版本,原始版本將由Hibernate負責維護,復制版本將由用戶使用,原始版本用作稍后的臟數據檢查一句;Hibernate
         * 將在臟數據檢查過程中將這2個版本的數據進行比對,如果數據發生了變化,則執行對應的持久化操作。
         * 數據發生了變化,則執行對應的持久化操作。
         
    */
        
    public Object deepCopy(Object value)throws HibernateException;
        
    /**
         * 本類型實例是否可變
         
    */
        
    public boolean isMutable();
    }

    posted @ 2009-10-16 15:59 王永慶 閱讀(162) | 評論 (0)編輯 收藏
    Java Transaction API(Java事務API) (JTA)Java Transaction API(Application Programming Interface)


    什么是JTA Transaction?它有怎樣的特點呢?JTA Transaction是指由J2EE Transaction manager去管理的事務。其最大的

    特點是調用UserTransaction接口的begin,commit和rollback方法來完成事務范圍的界定,事務的提交和回滾。JTA

    Transaction可以實現同一事務對應不同的數據庫,但是它仍然無法實現事務的嵌套。



    分布式事務的規范由OMG的OTS所描述。   
    JTA是只是一組java接口用于描述,J2ee框架中事務管理器與應用程序,資源管理器,以及應用服務器之間的事務通訊。   
    它主要包括高層接口即面向應用程序的接口;XAResource接口即面向資源的接口;以及事務管理器的接口。值得注意的是JTA

    只提供了接口,沒有具體的實現。   
    JTS是服務OTS的JTA的實現。簡單的說JTS實現了JTA接口,并且符合OTS的規范。   
       
    資源管理器只要其提供給事務管理器的接口符合XA接口規范,就可以被事務管理器處理。   
       
    所以,JTA可以處理任何提供符合XA接口的資源。包括:數據庫,JMS,商業對象等等  


    “Java 事務 API”(JTA)啟用兩階段提交功能。當配置 WebSphere Application Server 以訪問數據庫時,可選擇具有

    JTA 能力的驅動程序。如果需要兩階段提交功能,則必須使用啟用 JTA 的驅動程序。
    只要您在事務中調用了多個數據庫連接,就需要 JTA。只要您在事務中調用了多個數據庫服務器,就需要兩階段提交。這些

    連接可以是相同的物理數據庫服務器或多個數據庫服務器。例如:

        * 實體企業 Bean Entity1 在應用程序服務器 AppServer1 中部署。
        * 實體企業 Bean Entity2 在應用程序服務器 AppServer1 中部署。
        * 會話企業 Bean Session1 在應用程序服務器 AppServer1 中部署。

    如果 Session1 對同一事務內的 Entity1 和 Entity2 調用了方法而這兩個企業 Bean 正在使用不同的物理數據庫連接,則

    必須對 Entity1 和 Entity2 使用的數據源啟用 JTA。當從相同的數據源對象獲取那些連接時,這也是成立的。這需要具有

    JTA 能力的驅動程序以提交事務。
    當事務涉及到多個進程時,JTA 也是必需的。例如,一個事務可能會涉及在多個應用程序服務器中部署的企業 Bean。

        * 實體企業 Bean Entity1 在應用程序服務器 AppServer1 中部署。
        * 實體企業 Bean Entity2 在應用程序服務器 AppServer2 中部署。
        * 會話企業 Bean Session1 在應用程序服務器 AppServer1 中部署。

    如果 Session1 對同一事務(此事務構成一個分布式事務)內的 Entity1 和 Entity2 調用了方法,則必須對 Entity1 和

    Entity2 使用的數據源啟用 JTA。
    性能實現JTA 啟用的連接與非 JTA 啟用的連接執行情況不同。基于此原因,如果您的應用程序不需要 JTA,則最好使用非

    JTA 啟用的驅動程序。
    posted @ 2009-10-16 14:23 王永慶 閱讀(767) | 評論 (0)編輯 收藏
    class屬性有一下幾種類型:
    1、Assiged:主鍵由應用邏輯產生,數據交由Hibernate保存時,主鍵值已經設置完畢,無需Hibernate干預。
    2、hilo:通過hi/lo算法實現的主鍵生成機制,需要額外的數據庫表保存主鍵生成歷史狀態。
    3、與hilo類似,通過hi/lo算法實現的主鍵生成機制,只是主鍵歷史狀態保存在Sequence中,適用于支持Sequence的數據庫。
    4、incremaent:主鍵按數值順序遞增。此方式的實現機制為在當前應用中維持一個變量,以保存著當前的最大值,之后每次需要生成主鍵的時候將此值加1作為主鍵。如果同一數據庫有多個實例訪問,此方式必須避免使用。
    5、identity:采用數據庫提供的主鍵生成機制.
    6、sequence:采用數據庫提供的sequence機制生成主鍵
    7、native:由Hibernate根據數據庫適配器中的定義,自動采用identity、hilo、sequence的其中一種作為主鍵生成方式。
    8、uuid.hex:這種主鍵生成機制在最大程度上保證了產生ID的唯一性。
    9、uuid.string:與uuid.hex類似。
    10、foreign:使用外部表的字段作為主鍵。

        由于常用的數據庫,如SQLServer、MySql等,都提供了易用的主鍵生成機制。我們可以在數據庫提供的主鍵生成機制上,采用generator-class=native的主鍵生成方式。
        不過,值得注意的是,一些數據庫提供的主鍵生成機制在效率上未必最佳,大量并發insert數據時可能會引起表之間的互鎖。
        數據庫提供的主鍵生成機制,往往是通過在一個內部表中保存當前主鍵狀態,之后每次插入數據會讀取這個最大值,然后加上遞增量作為新記錄的主鍵值,之后再把這個新的最大值更新回內部表中,這樣,一次Insert操作可能導致數據庫內部多次表讀寫操作,同時伴隨的還有數據的加鎖解鎖操作,這對性能產生了很大影響。
        另外,對于借用Sequence作為主鍵產生機制的數據庫而言,如Oracle,如果采用<generator class="sequence">設定,那么插入一條新的數據之前,Hibernate必須首先向數據庫發起一條select sequence操作以獲取主鍵值。
        這樣,一次保存操作實際上包含了2個過程,首先查詢sequence獲得主鍵,其次執行Insert插入記錄,無疑操作效率相對較低。
        大多數情況下,如果邏輯允許,可以考慮使用uuid.hex主鍵生成方式。

        Hibernate3同時還提供了另一種與實體類型無關的映射方式:動態模型(Dynamic Model),所謂動態模型,即通過通用數據容器(Map)對庫表記錄進行表達。
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        
    <class entity-name="DynamicUserMap" table="T_User">
            
    <id name="id" column="id" type="java.lang.Integer">
                
    <generator class="native"/>
            
    </id>
            
    <property name="name" type="java.lang.String" column="name"/>
            
    <property name="age" type="java.lang.Integer" column="age"/>
        
    </class>
    </hibernate-mapping>

    操作示例:
    session = sessionFactory.openSession().getSession(EntityMode.MAP);
    Map userMap 
    = new HashMap();
    userMap.put(
    "name","ken");
    userMap.put(
    "age",new Integer(25));

    Transaction tx 
    = session.beginTransaction();
    session.save(
    "DynamicUserMap",userMap);
    tx.commit();

    首先,我們以EntityMode.MAP模式獲取Session實例,以此表明Session操作的對象并非普通的實體類,而是Map類型數據。
    其次,在執行實體操作時,須指明要操作的實體名:
    session.save("DynamicUserMap",userMap);

    posted @ 2009-10-16 14:22 王永慶 閱讀(219) | 評論 (0)編輯 收藏
        為了使用Hibernate的Transaction API,我們必須通過hibernate.transaction.factory_class屬性指定一個Transaction實例工廠類。Transaction API隱藏了底層的事務機制,允許Hibernate代碼在受管制和非受管制的環境下都可以進行。

    使用JDBC的事務處理機制:
    hibernate.transaction.factory_class net.sf.hibernate.transaction.JDBCTransactionFactory
    使用JTA
    hiberante.transaction.factory_class net.sf.hibernate.transaction.JTATransactionFactory
    jta.UserTransaction jta/usertransaction
        O/R映射關系無疑是ORM框架中最為關鍵的組成部分,在進行Hibernate實體屬性映射關系定義時,需要提供屬性的數據類型設定,通過這些類型定義,Hibernate即可完成Java數據類型到數據庫特定數據類型的映射關系。
        實體映射技術作為類與表之間的聯系紐帶,在ORM實現中起著至關重要的作用。
        實體映射的核心內容,即實體類與數據庫表之間的映射定義。Hibernate中,類表映射主要包括3個部分內容:
        a、表名-類名映射
        b、主鍵映射
        c、字段映射
       
    <?xml version="1.0" encoding="UTF-8"?>
        
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
         http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd
    >
        
    <hibernate-mapping>
          
    <class name="com.redsage.hibernate.db.entity.TUser" table="T_USER"/>
          
    <id name="id" column="id" type="java.lang.Integer">
            
    <generator class="native"/>
          
    </id>
          
    <property name="name" column="name" type="java.lang.String"/>
          
    <property name="age" column="age" type="java.lang.Integer"/>
         
    </class>
        
    </hibernate-mapping>
        XML文件頭定義了本XML文檔所采用的編碼方式:encoding="UTF-8".并指定了當前XML的DTD,DTD文件對當前XML文檔中的節點進行定義,這樣我們加載配置文件之前,可通過指定的DTD對當前XML中的節點進行檢查,確定XML結構和數據類型是否合法。
        通過CLASS節點的配置,hibernate即可獲知類與表的映射關系,即每個TUser類對象對應T_User表中的一條記錄。
        ID節點定義類實體類的標示(identity),在這里也就是對應庫表主鍵的類屬性,name="id"指定了當前映射類中的屬性"id"對應了T_User表中的主鍵字段。
        column="id"指定了當前映射表T_User唯一標示為"id"字段.id字段是T_User表的一個自增型字段,同時也是T_User表的主鍵。通過id字段我們即可唯一定位一條記錄。
        type="java.lang.Integer"指定了當前字段的數據類型。
        <generator class="native"/>指定了主鍵生成方式,這里的class="native"設定,意味著將主鍵生成機制的實現方式交由hibernate決定,hibernate將根據底層數據庫適配器的定義,采用不同數據庫特定的主鍵生成方式。
       
    posted @ 2009-10-15 14:58 王永慶 閱讀(206) | 評論 (0)編輯 收藏
    僅列出標題
    共7頁: 上一頁 1 2 3 4 5 6 7 下一頁 
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(1)

    隨筆分類

    隨筆檔案

    關注blogs

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 无码专区永久免费AV网站| 日本人的色道www免费一区| 久久免费区一区二区三波多野| 成年在线观看免费人视频草莓| 亚洲女子高潮不断爆白浆| 日本片免费观看一区二区| 亚洲av午夜福利精品一区| 91精品国产免费入口| 亚洲欧美日韩中文二区| 久久久久久久亚洲精品| 免费在线视频你懂的| 男男gvh肉在线观看免费| 免费观看大片毛片| 亚洲国产成人精品电影| 国产一精品一aⅴ一免费| 99视频精品全部免费观看| 亚洲综合激情另类小说区| 国产精品免费综合一区视频| 亚洲国产精品日韩av不卡在线 | 亚洲欧洲日产国码无码网站| 色影音免费色资源| a级毛片免费网站| 在线aⅴ亚洲中文字幕| 亚洲精品蜜桃久久久久久| 日本不卡在线观看免费v| 99热这里只有精品6免费| 无套内射无矿码免费看黄| 亚洲人成片在线观看| 亚洲V无码一区二区三区四区观看 亚洲αv久久久噜噜噜噜噜 | 免费福利资源站在线视频| 亚洲精品亚洲人成在线观看麻豆| 免费真实播放国产乱子伦| 在线观看无码AV网站永久免费| 国产在线播放线91免费| 亚洲国产成人AV网站| 亚洲人成色77777在线观看大| 老司机午夜精品视频在线观看免费| 亚洲精品国产高清不卡在线| 青青久在线视频免费观看| 亚洲精品免费观看| 成人网站免费看黄A站视频|