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

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

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

    love fish大鵬一曰同風(fēng)起,扶搖直上九萬里

    常用鏈接

    統(tǒng)計(jì)

    積分與排名

    friends

    link

    最新評(píng)論

    EJB3.0之操作Entity

    操作持久化Entity

    對Entity進(jìn)行操作的API都設(shè)計(jì)在javax.persistence.EntityManager接口上。EntityManager,顧名思義是管理所有EJB 3運(yùn)行環(huán)境中的所有Entity。 EntityManager根據(jù)運(yùn)行的環(huán)境不同分為容器管理的EntityManager和應(yīng)用管理的EntityManager。Liberator EJB3是一個(gè)可以運(yùn)行在J2SE環(huán)境中的 嵌入式的EJB3 Persistence實(shí)現(xiàn),因此在Liberator EJB3中的 EntityManager都是指應(yīng)用管理的EntityManager。

    配置和獲得EntityManager

    在J2SE環(huán)境中,EJB3定義了一個(gè)javax.persistence.Persistence類用于啟動(dòng)EJB3運(yùn)行環(huán)境。要獲得EntityManager,首先需要通過javax.persistence.Persistence獲得EntityManagerFactory,然后調(diào)用EntityManagerFactory.createEntityManager()方法獲得。
                    
        // 獲得默認(rèn)當(dāng)前的EntityManagerFactory                
        final EntityManagerFactory emf = Persistence.createEntityManagerFactory();
        final EntityManager entityManager = emf.createEntityManager();    
                    
                

    當(dāng)調(diào)用Persistence.createEntityManagerFactory()的時(shí)候,Persistence會(huì)做以下的步驟:

    • 搜索當(dāng)前jar包的META-INFO/persistence.xml配置文件
    • 如果沒有在META-INFO下找到persistence.xml,搜索當(dāng)前線程的ContextClassLoader中的persistence.xml
    • 根據(jù)獲得的persistence.xml初始化EntityManagerFactory
    每個(gè)EntityManagerFactory都必須有一個(gè)persistence.xml配置文件。下面是一個(gè)例子:
                    
    <entity-manager>
        <name>myEntityManager</name>
        <provider>com.redsoft.ejb3.PersistenceProviderImpl</provider>
        <class>com.redsoft.samples.HelloEntityBean</class>
        <properties>
            <property name="ConnectionDriverName" value="com.mysql.jdbc.Driver"/>
            <property name="ConnectionURL" value="jdbc:mysql://localhost/EJB3Test"/>
            <property name="ConnectionUserName" value="ejb3"/>
            <property name="ConnectionPassword" value="ejb3"/>
            <property name="RetainValues" value="true"/>
            <property name="RestoreValues" value="false"/>
            <property name="IgnoreCache" value="false"/>
            <property name="NontransactionalRead" value="true"/>
            <property name="NontransactionalWrite" value="false"/>
            <property name="Multithreaded" value="false"/>
            <property name="Liberator.option.action" value="create"/>
            <property name="Liberator.option.cache" value="com.redsoft.jdo.enterprise.OscacheAdapter"/>
            <property name="Liberator.option.JMXEnabled" value="false"/>
            <property name="Liberator.option.NamingPort" value="3012"/>
            <property name="Liberator.option.JMXPort" value="3011"/>
            <property name="Liberator.option.JDBC.scrollable" value="false"/>
            <property name="Liberator.option.JDBC.fetchSize" value="500"/>
            <property name="cache.algorithm" value="LRUCache"/>
            <property name="cache.capacity" value="5000"/>
            <property name="log4j.logger.com.redsoft" value="FATAL"/>
        </properties>
    </entity-manager>   
                    
                

    <name></name> 定義一個(gè)EntityManagerFactory的名字,這樣當(dāng)應(yīng)用中需要多個(gè)EntityManagerFactory的時(shí)候可以區(qū)別。通常情況下,一個(gè)EntityManagerFactory對應(yīng)一個(gè)數(shù)據(jù)源。

    <provider></provider> 定義采用的什么EJB3 Persistence運(yùn)行環(huán)境(也就是EJB3 Persistence產(chǎn)品),例子中采用的的是Liberator EJB3的運(yùn)行環(huán)境。正如前面說的,在EJB3規(guī)范中, EJB3 Persistence運(yùn)行環(huán)境( Runtime )是作為一個(gè)獨(dú)立的嵌入式模塊,你可以隨意的更換不同的EJB3 Persistence運(yùn)行環(huán)境而不會(huì)影響你的應(yīng)用程序。甚至在J2EE服務(wù)器內(nèi)運(yùn)行你也可以不用服務(wù)器本身提供的EJB3 Persistence運(yùn)行環(huán)境,而采用第三方的EJB3 Persistence運(yùn)行環(huán)境

    <class></class> 定義哪些類是Entity持久化類。如果是測試環(huán)境或者你不采用ear/war的方式發(fā)布你的應(yīng)用,而只是把編譯后的類直接拷貝到web容器中,在添加一個(gè)新的Entity類時(shí),需要在這里添加一行。要求這個(gè)步驟是因?yàn)樵贘2EE 5架構(gòu)中EJB3運(yùn)行環(huán)境的嵌入式設(shè)計(jì)。采用這種松耦合設(shè)計(jì)使EJB3 Persistence運(yùn)行環(huán)境不能控制持久化類的加載(由J2EE服務(wù)器負(fù)責(zé)加載), 這樣EJB3 Persistence運(yùn)行環(huán)境就無法分辨jvm中哪個(gè)類是持久化Entity類,哪個(gè)不是。因此需要一個(gè)額外的信息來讓EJB3 Persistence知道那些是持久化Entity。

    <property></property> 定義了了EJB3 Persistence運(yùn)行環(huán)境需要的其他參數(shù),這些參數(shù)不是標(biāo)準(zhǔn)的,而是由EJB3 Persistence運(yùn)行環(huán)境的廠商自行定義。

    詳細(xì)的配置方法參看persistence.xml的語法。

    Entity的生命周期和狀態(tài)

    在EJB3中定義了四種Entity的狀態(tài):
    • 新實(shí)體(new)。Entity由應(yīng)用產(chǎn)生,和EJB3 Persistence運(yùn)行環(huán)境沒有聯(lián)系,也沒有唯一的標(biāo)示符(Identity)。
    • 持久化實(shí)體(managed)。新實(shí)體和EJB3 Persistence運(yùn)行環(huán)境產(chǎn)生關(guān)聯(lián)(通過persist(), merge()等方法),在EJB3 Persistence運(yùn)行環(huán)境中存在和被管理,標(biāo)志是在EJB3 Persistence運(yùn)行環(huán)境中有一個(gè)唯一的標(biāo)示(Identity)。
    • 分離的實(shí)體(detached)。Entity有唯一標(biāo)示符,但它的標(biāo)示符不被EJB3 Persistence運(yùn)行環(huán)境管理, 同樣的該Entity也不被EJB3 Persistence運(yùn)行環(huán)境管理。
    • 刪除的實(shí)體(removed)。Entity被remove()方法刪除,對應(yīng)的紀(jì)錄將會(huì)在當(dāng)前事務(wù)提交的時(shí)候從數(shù)據(jù)庫中刪除。

    持久化Entity(Persist)

                    
        final EntityManagerFactory emf = Persistence.createEntityManagerFactory();
        final EntityManager entityManager = emf.createEntityManager();
    
        final HelloEntityBean hello = new HelloEntityBean( 1, "foo" );
        EntityTransaction trans = entityManager.getTransaction();
        trans.begin();
        
        // 持久化hello,在此操作之前hello的狀態(tài)為new
        entityManager.persist( hello );
        
        // 這時(shí)hello的狀態(tài)變?yōu)閙anaged
        
        trans.commit();
    
        entityManager.close();
        
        // 這時(shí)hellow的狀態(tài)變?yōu)閐etached.
        
                     
                
    Liberator EJB3支持Persistence by reachability。當(dāng)保存一個(gè)Entity時(shí),以該對象為根對象的整個(gè)對象圖都會(huì)自動(dòng)的被保存。但在EJB3中,我們?nèi)匀豢梢酝ㄟ^關(guān)系元數(shù)據(jù)(比如OneToOne,OneToMany)的cascade屬性來精確定義保存的級(jí)聯(lián)行為。 下面我們來看看不同的cascade屬性的區(qū)別。

    不配置cascade的情況下,EJB3 Persistence運(yùn)行環(huán)境默認(rèn)不會(huì)采用Persistence by reachability。

                    
        public class Father{
            @Id
            int id
            
            String name;
            
            // OneToOne沒有配置cascade屬性,因此默認(rèn)不會(huì)使用Persistence by reachablity
            @OneToOne
            Son mySon
            
            public Father( int id, String name, Son mySon ){
                this.id = id;
                this.name = name;
                this.mySon = mySon;
            }
        }
                      
    現(xiàn)在來保存一個(gè)Father和Son。
                    
        final EntityManager manager = emf.createEntityManager();
        manager.getTransaction().begin;
        
        Son mySon = new Son();
        Father = new Father( 1, "father" mySon );
        
        // 保存Father
        manager.persist( father );
        
        // 由于OneToOne關(guān)系中沒有配置casacade屬性,father 關(guān)聯(lián)的mySon不會(huì)被自動(dòng)保存,需要分別保存
        manager.persist( mySon );
        manager.getTransaction().commit();
        manager.close();
                     
    現(xiàn)在我們配置casacde=CascadeType.ALL
                    
        public class Father{
            @Id
            int id
            
            String name;
            
            // OneToOne配置cascade=CascadeType.ALL,配置cascade=CascadeType.PERSIT也對persist操作也可以獲得同樣的效果。
            // CascadeType.ALL包含CascadeType.PERSIST。
            @OneToOne(cascade=CascadeType.ALL)
            Son mySon
            
            public Father( int id, String name, Son mySon ){
                this.id = id;
                this.mySon = mySon;
                this.name = name;
            }
        }
                      
    在代碼中同樣持久化Father和mySon。
                    
        final EntityManager manager = emf.createEntityManager();
        manager.getTransaction().begin;
        
        Son mySon = new Son();
        Father = new Father( 1, mySon );
        
        // 保存Father。由于OneToOne關(guān)系中配置casacade=CascadeType.ALL屬性,關(guān)聯(lián)的mySon會(huì)自動(dòng)地被持久化
        manager.persist( father );
        manager.getTransaction().commit();
        manager.close();
                     
    由于Liberator EJB3運(yùn)行環(huán)境采用了弱引用POJO管理技術(shù),能很好的支持Persistence by reachablity而不會(huì)有其他產(chǎn)品有的潛在內(nèi)存回收的問題, 因此建議在應(yīng)用中盡可能使用cascade=CascadeType.ALL來減少持久化操作的復(fù)雜性和代碼量,特別是在有復(fù)雜對象關(guān)系圖的時(shí)候。

    獲取Entity

    如果知道Entity的唯一標(biāo)示符,我們可以用find()方法來獲得Entity。
                            
        Father father = manager.find( Father.class, new Integer( 1 ) );
                
        // 由于JDK1.5支持自動(dòng)轉(zhuǎn)型,也可以如下使用
                
        Father father = manager.find( Father.class, 1 );
        
        /* 
        * 或者,可以用Entity名字作為查找。但無法利用JDK 1.5的自動(dòng)轉(zhuǎn)型功能,
        *  需要使用對象作為查找主鍵,并需要對獲得Entity進(jìn)行轉(zhuǎn)型
        */
        
        Father father = (Father)manager.find( "com.redsoft.samples.Father", new Integer( 1 ) );
                
              

    更新Entity

    對Entity的更新必須在事物內(nèi)完成。和persist中一樣,關(guān)系元數(shù)據(jù)的cascade屬性對是否集聯(lián)刪除有影響。
                    
        transaction.begin();                
        Father father = manager.find( Father.class, 1 );
        
        // 更新原始數(shù)據(jù)類型
        father.setName( "newName" );
        
        // 更新對象引用
        Son newSon = new Son();
        father.setSon( newSon );
        
        
        // 提交事務(wù),剛才的更新同步到數(shù)據(jù)庫
        transaction.commit();
                     

    刪除Entity

    對Entity的刪除必須在事物內(nèi)完成。
                    
        transaction.begin();                
        
        Father father = manager.find( Father.class, 1 );
            
        // 如果father/son的@OneToOne的cascade=CascadeType.ALL,在刪除father時(shí)候,也會(huì)把son刪除。
        // 把cascade屬性設(shè)為cascade=CascadeType.REMOVE有同樣的效果。
        manager.remove( father );
            
        // 提交事務(wù),剛才的更新同步到數(shù)據(jù)庫
        transaction.commit();
                     

    脫離/附合(Detach/Merge)

    在三層或者分布式應(yīng)用中,我們很多時(shí)候需要Entity能脫離EntityManager,避免長時(shí)間保持EntityManager打開占用資源和可以在不同的JVM之間傳遞Entity。

    在脫離EJB3 Persistence Runtime(EntityManager)的管理后,我們?nèi)匀豢梢宰x取或者修改Entity中的內(nèi)容。而在稍后的時(shí)間,我們又可以將Entity重新和原有或者新的EntityManager附合,如果附合前Entity被改動(dòng)過,更改的數(shù)據(jù)可以自動(dòng)的被發(fā)現(xiàn)并和數(shù)據(jù)庫同步。

                    
        EntityManager entityManager = emf.createEntityManager();
        
        // 這時(shí)Father還是被EntityManager管理的
        Father father = manager.find( Father.class, 1 );
        
        // 當(dāng)entityManger關(guān)閉的時(shí)候,當(dāng)前被entityManager管理的Entity都會(huì)自動(dòng)的脫離EntityManager,狀態(tài)轉(zhuǎn)變?yōu)閐etached
        entityManager.close();
        
        // 脫離EntityManager后,我們?nèi)匀豢梢孕薷腇ather的屬性
        father.setName( "newName" );
        
        // 在稍后的,我們可以將father重新附和到一個(gè)新的或者原來的EntityManager中
        EntityManager newEntityManager = emf.createEntityManager();
        
        // 附合( merge )需要在事務(wù)中進(jìn)行
        newEntityManager.getTransaction().begin();
        newEntityManager.merge( father );
        
        // commit后father中的被修改的內(nèi)容會(huì)同步到數(shù)據(jù)庫。
        newEntityManager.getTransaction().commit();
        
    
                     

    Liberator EJB3 Persistnece運(yùn)行環(huán)境由于支持Persistence-by-reachablity。我們建議采用cascade=CascadeType.ALL,這樣當(dāng)需要附合的是一個(gè)對象圖的時(shí)候,我們只需要merge根對象即可,整個(gè)對象圖,對象圖中被修改過的對象都會(huì)被自動(dòng)識(shí)別和同步。

    需要注意的是在脫離EJB3 Persistence Runtime的管理后,如果對象中有定義為lazy-load的屬性將無法訪問。

    posted on 2006-07-03 00:57 liaojiyong 閱讀(1159) 評(píng)論(0)  編輯  收藏 所屬分類: EJB

    主站蜘蛛池模板: 国内精品免费在线观看| 18禁网站免费无遮挡无码中文| 亚洲av午夜福利精品一区人妖| 亚洲免费视频在线观看| 久久精品免费全国观看国产| 免费精品久久久久久中文字幕| 久久亚洲成a人片| 波多野结衣中文一区二区免费| 九九精品成人免费国产片| 亚洲最大福利视频| 中文字幕日韩亚洲| A在线观看免费网站大全| jizz免费一区二区三区| 亚洲av永久无码精品三区在线4| 亚洲裸男gv网站| 久久久久久99av无码免费网站| 国产精品免费αv视频| 亚洲国产乱码最新视频| 亚洲日韩aⅴ在线视频| 日韩免费观看的一级毛片| 99在线免费观看| 亚洲日本一线产区和二线| 亚洲91av视频| 亚洲男人在线无码视频| 免费无码A片一区二三区| 久久久精品免费国产四虎| 香港特级三A毛片免费观看| 亚洲精品网站在线观看你懂的| 亚洲片一区二区三区| 国产精品久久久久久久久久免费| 久久国产乱子精品免费女| 美女黄色免费网站| 亚洲色图激情文学| 亚洲综合一区二区| 久久精品国产亚洲一区二区| 亚洲精品无码99在线观看| 成人午夜免费福利| 在线看片v免费观看视频777 | 亚洲欧美成aⅴ人在线观看| 亚洲av无码一区二区三区网站 | 在线成人爽a毛片免费软件|