`
senton
  • 浏览: 205991 次
  • 性别: 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

    **企业级JavaBeans(EJB)3.0详解** 企业级JavaBeans(Enterprise JavaBeans,简称EJB)是Java平台上用于构建分布式...《EJB 3.0实例教程》这本书应该会详细解释这些概念,并通过实例帮助读者掌握EJB 3.0的实践应用。

    EJB3.0实例教程(PDF)

    **EJB3.0实例教程**是一份详细指导开发者如何使用Enterprise JavaBeans 3.0(EJB3.0)技术进行企业级应用开发的电子文档。EJB3.0是Java EE(Java Platform, Enterprise Edition)规范的一部分,旨在简化企业级组件的...

    电子书-EJB3.0实例教程

    通过《EJB 3.0实例教程》这本书,读者可以深入理解这些概念,并通过实际案例学习如何在项目中运用EJB 3.0。书中可能涵盖了创建和配置EJB组件、使用JPA进行ORM、设计事务策略、编写JPQL查询以及管理Bean的生命周期等...

    EJB3.0实例教程及源代码

    **EJB3.0实例教程及源代码** 本教程专注于企业级JavaBeans(EJB)3.0技术的实践应用,由黎活明提供。EJB是Java平台上的一个核心组件,用于构建可扩展的、可靠的、安全的分布式应用程序。EJB 3.0是EJB规范的一个重要...

    ejb3.0入门图文教程

    在整个学习过程中,你将了解到EJB 3.0的核心概念,如依赖注入、容器管理的事务、安全性和性能优化。这些知识对于理解和构建企业级Java应用程序至关重要。同时,EJB 3.0的可读性强和简洁的编程模型也使其成为开发者...

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

    在《中文最新EJB3.0实例教程》中,你将学习如何创建和部署EJB3.0组件,如何使用JPA进行数据持久化,以及如何利用依赖注入和事务管理构建可扩展和可靠的业务应用。教程中可能包含实际的项目案例,通过实践操作来加深...

    EJB3.0入门教程 PDF

    **企业级JavaBeans(EJB)3.0入门教程** EJB(Enterprise JavaBeans)是Java平台企业版(Java EE)的核心组件之一,用于构建可扩展、安全且可靠的分布式企业应用。EJB 3.0是该技术的一个重大革新,引入了许多简化...

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

    **企业级JavaBeans(EJB)3.0详解** 企业级JavaBeans(EJB)是Java平台上用于构建可部署在企业级服务器上的组件模型。...学习这个教程,你将能够掌握EJB 3.0的核心概念,并有能力创建和部署自己的EJB组件。

    精通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实例教程 ejb3.0实例教程 ejb3.0实例教程

    EJB3.0入门图文教程

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

    EJB3.0实例教程源码

    本实例教程将专注于EJB 3.0中的多对多映射,这是关系数据库与对象模型之间关系映射的一种常见模式。 多对多映射在现实世界中很常见,例如在学生和老师的关系中,一个学生可以有多个老师,同时一个老师也可以教多个...

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

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

    EJB3.0入门教程

    **EJB3.0入门教程** 企业级JavaBean(Enterprise JavaBeans,EJB)是Java平台上用于构建可扩展、安全且事务处理能力强大的企业级应用的框架。EJB3.0是EJB技术的一个重大革新,它极大地简化了开发过程,降低了对...

    EJB学习大全(EJB3.0实例教程 JPA教程 实战EJB)

    【EJB学习大全】是针对企业级Java应用开发的一个重要主题,主要涵盖了EJB3.0、JPA教程以及实战EJB的相关知识。EJB,全称为Enterprise JavaBeans,是Java平台上的一个核心组件,主要用于构建分布式、面向服务的企业级...

Global site tag (gtag.js) - Google Analytics