`
senton
  • 浏览: 200977 次
  • 性别: Icon_minigender_1
  • 来自: 紫禁城
社区版块
存档分类
最新评论

EJB3.0 学习教程(连载) 第三部分

阅读更多
 
                     第三部分 持久化
3.1    操作持久化Entity
对Entity进行操作的API都设计在javax.persistence.EntityManager接口上。EntityManager,顾名思义是管理所有EJB 3运行环境中的所有Entity。 EntityManager根据运行的环境不同分为容器管理的EntityManager和应用管理的EntityManager。Liberator EJB3是一个可以运行在J2SE环境中的 嵌入式的EJB3 Persistence实现,因此在Liberator EJB3中的 EntityManager都是指应用管理的EntityManager。
3.2    配置和获得EntityManager
在J2SE环境中,EJB3定义了一个javax.persistence.Persistence类用于启动EJB3运行环境。要获得EntityManager,首先需要通过javax.persistence.Persistence获得EntityManagerFactory,然后调用EntityManagerFactory.createEntityManager()方法获得。
               
    // 获得默认当前的EntityManagerFactory               
    final EntityManagerFactory emf = Persistence.createEntityManagerFactory();
    final EntityManager entityManager = emf.createEntityManager();            
当调用Persistence.createEntityManagerFactory()的时候,Persistence会做以下的步骤:
  • 搜索当前jar包的META-INFO/persistence.xml配置文件
  • 如果没有在META-INFO下找到persistence.xml,搜索当前线程的ContextClassLoader中的persistence.xml
  • 根据获得的persistence.xml初始化EntityManagerFactory
每个EntityManagerFactory都必须有一个persistence.xml配置文件。下面是一个例子:
               
<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> 定义一个EntityManagerFactory的名字,这样当应用中需要多个EntityManagerFactory的时候可以区别。通常情况下,一个EntityManagerFactory对应一个数据源。
<provider></provider> 定义采用的什么EJB3 Persistence运行环境(也就是EJB3 Persistence产品),例子中采用的的是Liberator EJB3的运行环境。正如前面说的,在EJB3规范中, EJB3 Persistence运行环境( Runtime )是作为一个独立的嵌入式模块,你可以随意的更换不同的EJB3 Persistence运行环境而不会影响你的应用程序。甚至在J2EE服务器内运行你也可以不用服务器本身提供的EJB3 Persistence运行环境,而采用第三方的EJB3 Persistence运行环境
<class></class> 定义哪些类是Entity持久化类。如果是测试环境或者你不采用ear/war的方式发布你的应用,而只是把编译后的类直接拷贝到web容器中,在添加一个新的Entity类时,需要在这里添加一行。要求这个步骤是因为在J2EE 5架构中EJB3运行环境的嵌入式设计。采用这种松耦合设计使EJB3 Persistence运行环境不能控制持久化类的加载(由J2EE服务器负责加载), 这样EJB3 Persistence运行环境就无法分辨jvm中哪个类是持久化Entity类,哪个不是。因此需要一个额外的信息来让EJB3 Persistence知道那些是持久化Entity。
<property></property> 定义了了EJB3 Persistence运行环境需要的其他参数,这些参数不是标准的,而是由EJB3 Persistence运行环境的厂商自行定义。
详细的配置方法参看persistence.xml的语法。
3.3    Entity的生命周期和状态
在EJB3中定义了四种Entity的状态:
  • 新实体(new)。Entity由应用产生,和EJB3 Persistence运行环境没有联系,也没有唯一的标示符(Identity)。
  • 持久化实体(managed)。新实体和EJB3 Persistence运行环境产生关联(通过persist(), merge()等方法),在EJB3 Persistence运行环境中存在和被管理,标志是在EJB3 Persistence运行环境中有一个唯一的标示(Identity)。
  • 分离的实体(detached)。Entity有唯一标示符,但它的标示符不被EJB3 Persistence运行环境管理, 同样的该Entity也不被EJB3 Persistence运行环境管理。
  • 删除的实体(removed)。Entity被remove()方法删除,对应的纪录将会在当前事务提交的时候从数据库中删除。
3.4    持久化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的状态为new
    entityManager.persist( hello );
   
    // 这时hello的状态变为managed
   
    trans.commit();
 
    entityManager.close();
   
    // 这时hellow的状态变为detached.                
           
Liberator EJB3支持Persistence by reachability。当保存一个Entity时,以该对象为根对象的整个对象图都会自动的被保存。但在EJB3中,我们仍然可以通过关系元数据(比如OneToOne,OneToMany)的cascade属性来精确定义保存的级联行为。 下面我们来看看不同的cascade属性的区别。
不配置cascade的情况下,EJB3 Persistence运行环境默认不会采用Persistence by reachability。              
    public class Father{
        @Id
        int id
       
        String name;
       
        // OneToOne没有配置cascade属性,因此默认不
        // 会使用Persistence by reachablity
        @OneToOne
        Son mySon
       
        public Father( int id, String name, Son mySon ){
            this.id = id;
            this.name = name;
            this.mySon = mySon;
        }
    }
                 
现在来保存一个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关系中没有配置casacade属性,father 关联的mySon
// 不会被自动保存,需要分别保存
    manager.persist( mySon );
    manager.getTransaction().commit();
    manager.close();
                
现在我们配置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关系中配置casacade=CascadeType.ALL属// 性,关联的mySon会自动地被持久化
    manager.persist( father );
    manager.getTransaction().commit();
    manager.close();
                
由于Liberator EJB3运行环境采用了弱引用POJO管理技术,能很好的支持Persistence by reachablity而不会有其他产品有的潜在内存回收的问题, 因此建议在应用中尽可能使用cascade=CascadeType.ALL来减少持久化操作的复杂性和代码量,特别是在有复杂对象关系图的时候。
3.5    获取Entity
如果知道Entity的唯一标示符,我们可以用find()方法来获得Entity。
                       
    Father father = manager.find( Father.class, new Integer( 1 ) );
            
    // 由于JDK1.5支持自动转型,也可以如下使用
           
    Father father = manager.find( Father.class, 1 );
   
    /*
    * 或者,可以用Entity名字作为查找。但无法利用JDK 1.5的自动转型功能,
    * 需要使用对象作为查找主键,并需要对获得Entity进行转型
    */
   
    Father father = (Father)manager.find( "com.redsoft.samples.Father", new Integer( 1 ) );
           
3.6    新Entity
对Entity的更新必须在事物内完成。和persist中一样,关系元数据的cascade属性对是否集联删除有影响。
               
    transaction.begin();               
    Father father = manager.find( Father.class, 1 );
   
    // 更新原始数据类型
    father.setName( "newName" );
   
    // 更新对象引用
    Son newSon = new Son();
    father.setSon( newSon );
   
   
    // 提交事务,刚才的更新同步到数据库
    transaction.commit();
                
3.7    删除Entity
对Entity的删除必须在事物内完成。
               
   transaction.begin();               
   
    Father father = manager.find( Father.class, 1 );
       
    // 如果father/son的@OneToOne的cascade=CascadeType.ALL,在删除father时候,也会把son删除。
    // 把cascade属性设为cascade=CascadeType.REMOVE有同样的效果。
    manager.remove( father );
       
    // 提交事务,刚才的更新同步到数据库
    transaction.commit();
                
3.8    脱离/附合(Detach/Merge)
在三层或者分布式应用中,我们很多时候需要Entity能脱离EntityManager,避免长时间保持EntityManager打开占用资源和可以在不同的JVM之间传递Entity。
在脱离EJB3 Persistence Runtime(EntityManager)的管理后,我们仍然可以读取或者修改Entity中的内容。而在稍后的时间,我们又可以将Entity重新和原有或者新的EntityManager附合,如果附合前Entity被改动过,更改的数据可以自动的被发现并和数据库同步。               
    EntityManager entityManager = emf.createEntityManager();
   
    // 这时Father还是被EntityManager管理的
    Father father = manager.find( Father.class, 1 );
   
    // 当entityManger关闭的时候,当前被entityManager管理的Entity都会自动的脱离EntityManager,状态转变为detached
    entityManager.close();
   
    // 脱离EntityManager后,我们仍然可以修改Father的属性
    father.setName( "newName" );
   
    // 在稍后的,我们可以将father重新附和到一个新的或者原来的EntityManager中
    EntityManager newEntityManager = emf.createEntityManager();
   
    // 附合( merge )需要在事务中进行
    newEntityManager.getTransaction().begin();
    newEntityManager.merge( father );
   
    // commit后father中的被修改的内容会同步到数据库。
    newEntityManager.getTransaction().commit();
Liberator EJB3 Persistnece运行环境由于支持Persistence-by-reachablity。我们建议采用cascade=CascadeType.ALL,这样当需要附合的是一个对象图的时候,我们只需要merge根对象即可,整个对象图,对象图中被修改过的对象都会被自动识别和同步。
需要注意的是在脱离EJB3 Persistence Runtime的管理后,如果对象中有定义为lazy-load的属性将无法访问。 
分享到:
评论

相关推荐

    EJB 3.0实例教程.pdf

    EJB 3.0实例教程.pdf EJB 3.0实例教程.pdf

    ejb3.0实例教程.pdf

    ejb3.0实例教程.pdfejb3.0实例教程.pdf

    ejb3.0入门图文教程

    ejb3.0入门图文教程,包括EJB3.0开发Entity.pdf、EJB3.0开发Message Driven Bean.pdf、EJB3.0开发Session Bean.pdf

    EJB3.0实例教程(PDF)

    EJB3.0实例教程,电子文档,图例很丰富的进行EJB3.0程序的开发

    ejb3.0实例教程

    期待已久的 EJB3.0 最终规范已经发布了。虽然 EJB3.0 最终规范出来了一段时间,但对 EJB3.0 的应用还停留在介 ...因为 JBOSS EJB3.0 产品常未成熟,本教程随着新产品的推出将有所改动,请密切关注!

    EJB3.0入门教程 PDF

    EJB3.0入门教程,PDF高清版,主要讲了在JBUILDER中配置EJB3.0和在JBOSS中配置EJB3.0的相关知识,同时也介绍了一些入门级要点,适合初学者阅读。

    EJB3.0实例教程及源代码

    黎活明EJB3.0实例教程,及源代码,全套资源

    电子书-EJB3.0实例教程

    电子书-EJB3.0实例教程 不错的一本书,看看吧!

    精通EJB3.0 中文版 3/3

    总共3个zip文件 请全部下载后再解压 7zip压缩 罗时飞精通EJB3.0.zip.001 罗时飞精通EJB3.0.zip.002 罗时飞精通EJB3.0.zip.003 ...第三部分专注于高级EJB专题;第四部分是附录,收集了EJB组件技术相关的其他内容。

    EJB3.0实例教程

    EJB3.0实例教程 博文链接:https://brxonline.iteye.com/blog/153889

    精通EJB3.0 中文版 1/3

    总共3个zip文件 请全部下载后再解压 7zip压缩 罗时飞精通EJB3.0.zip.001 罗时飞精通EJB3.0.zip.002 罗时飞精通EJB3.0.zip.003 ...第三部分专注于高级EJB专题;第四部分是附录,收集了EJB组件技术相关的其他内容。

    最新EJB3.0实例教程

    最新EJB3.0实例教程 最新的 EJB3.0教材 为读者阅读。

    EJB3.0实例教程(源代码).rar )

    EJB3.0实例教程(源代码).rar )

    中文最新EJB3.0实例教程下载

    中文最新EJB3.0实例教程 博文链接:https://yongzhao.iteye.com/blog/44254

    EJB3.0入门图文教程

    EJB3.0入门图文教程电子书,Jbuilder 2007,新版JBuilder2007基于Eclipse平台,与以往的JBuilder版本完全不 同.借助于Eclipse的开放平台以及丰富的插件,使得JBulider对当前的流行的框架支持非 常好,同时支持EJB3.0的...

    传智播客_EJB3.0视频教程网盘下载

    传智播客_EJB3.0视频教程网盘下载,本教程仅供学习之用,请勿用于商用,一切后果自负。

Global site tag (gtag.js) - Google Analytics