[计算机软件及应用]EJB-3课件_第1页
[计算机软件及应用]EJB-3课件_第2页
[计算机软件及应用]EJB-3课件_第3页
[计算机软件及应用]EJB-3课件_第4页
[计算机软件及应用]EJB-3课件_第5页
已阅读5页,还剩120页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、EJB 3.0Enterprise JavaBeansEnterprise JavaBeans架构是一个用于开发和部署基于组件的分布式业务应用的组件架构。采用Enterprise JavaBeans架构编写的应用是可伸缩的、事务性的、多用户安全的。可以一次编写这些应用,然后部署于任何支持Enterprise JavaBeans规范的服务器平台上 Enterprise JavaBeans 是一个用于分布式业务应用的标准服务器端组件模型。服务器端组件一个服务器端组件模型可以定义一个用来开发分布式业务对象的架构,以便将针对分布式对象系统的访问组合起来,该系统体现了目标明确的业务逻辑的流动性。服务器端

2、组件模型被用于中间层的应用服务器,此类服务器在运行时管理组件,并使其可以被远程客户端访问到。依赖于组件模型,服务器管理员通过给属性设置特定取值,可以为服务器端组件声明事务、安全,甚至持久化行为。EJB的分类有三类基本的bean:entity,session,以及message-driven。Entity bean是持久化的,它代表着人,场所,或者事物。Session bean则是客户端的延伸,它包含着一个定义了其他bean如何交互的流程或任务流。Session bean不是持久化的:它们从客户端接受状态,并且只在客户端需要它们的时候才存在。Message-driven bean则是用于整合的,

3、它允许其他应用使用JMS或别的JCA1.5兼容资源与EJB应用进行交互。和stateless session bean一样,message-driven bean不用持久化,并且不维持会话状态。 Session BeanSession bean就像代理一样为客户端管理业务流程或任务,他们是安置业务逻辑的理想之所。Session bean时不必持久化的;在session bean里不存在任何直接映射到数据库或者存储于若干session 之间的信息。Session bean与entity bean、数据、还有其他用以控制任务流的资源一起工作。任务流是任何业务系统的本质所在,因为它表达了实体间如何交

4、互,用以模塑实际的业务。Session bean控制任务和资源,但它们自身并不代表实际数据代理存根和bean实例当你的业务逻辑与session bean交互时,它并不直接与bean class的实例打交道,而是经由bean的远程或本地接口。当调用远程或本地接口的方法时,你所使用的对象实例时一种被称为代理存根的东西。该代理存根实现了session bean的远程或本地接口,并且负责将你的session bean方法调用经过网络发生到远程EJB容器,或将请求路由到位于本地JVM内的EJB容器。代理存根可以由像RMI的rmic这样的预编译器生成,或者像JBoss那样,在部署期间使用JDK所带的jav

5、a.lang.reflect.Proxy动态生成。Session Bean将任务流逻辑移到session bean中还简化了客户端应用,降低了网络通信。过量的网络通信是分布式对象系统的常见问题:它能搞垮服务器和阻塞网络,损害响应时间和性能。如果使用得当,通过限制执行一项任务所需的请求数量,session bean能够减小网络通信流量。Sessoin bean的使用者将任务流所涉及的不同bean之间的彼此交互保持于服务器端。位于客户端应用的一次方法调用导致了服务器端的多次方法调用,但是网络所看到的仅仅是由客户端调用session bean所引起的通信流量。 Stateful和stateless

6、session beanSessoin bean既可以是有状态的,也可以是无状态的。当客户端使用stateless session bean时session bean就维持了会话状态。会话状态是不写入数据库的。它是客户端在维持与某一enterprise bean的会话时保存于内存中的信息,并且一旦会话结束或EJB容器崩溃,就会随即消失。 会话状态仅在客户端应用正在使用bean 的时候才会被保持。一旦客户端关闭或释放了Session Bean,会话状态就永久性消失了。Stateful Session Bean只为同一客户端提供服务。持久化和 Entity Beans持久化是位于 JDBC 之上的

7、一个更高层抽象。持久层将对象映射到数据库,以便在查询、装载、更新,或删除对象的时候,无须使用像 JDBC 那样繁琐的 API。在 EJB 的早期版本中,持久化是EJB 平台的一部分。从EJB 3.0 开始,持久化已经自成规范,被称为 Java Persistence API。Java Persistence API 定义了一种方法,可以将常规的普通 Java 对象(有时被称作 POJO)映射到数据库。这些普通 Java 对象被称作 entity bean。 Entity BeanJava Persistence1.0规范中的entity bean仅作为普通Java对象(POJO)来使用,并且是

8、映射到关系数据库表的。与其他类型的EJB不同,entity bean可以被分配,序列化,并像任何其他POJO那样通过网络被发送出去。用entity bean来模塑那些可以被表达成名词的业务概念。例如,一个entity bean可以代表一位顾客、一台设备、存货清单中的一项,或者一个地点。为了实现entity bean,你需要定义一个bean class,并选择合适的数据成员作为该bean class的标识(即主键)。主键是一种提供数据库指向的手段。它给予entity bean class以标识,即作为内存中的对象,也作为数据库里表中的一行。主键可以是一个类,也可以是基本类型(primitive

9、type)。持久化和 Entity Beans在 EJB 2.1 规范中,entity bean 非常笨重并且依赖于应用服务器和整个 Java EE 运行时环境。在 Java Persistence 里,entity bean 是受持久化服务管理的常规 Java 对象。与 EJB 2.1 不同,Java Persistence 中的 entity bean 并不要求实现任何规范特有的接口或类。旧规范的另一个缺点在于,它让每个厂商自行决定对象如何映射到数据库。这使得 EJB 2.1 的 entity bean通常无法在不同厂商间进行移植。新的 Java Persistence 规范定义了一个完备

10、的对象关系映射(ORM),如此,entity bean 便能够在厂商之间轻松移植。 持久化和 Entity Beans由于 entity bean在EJB3.0是普通Java对象了,它们不仅可以在应用服务器之间进行移植;还能用于应用服务器之外的常规Java应用程序,甚至可以用于客户端和服务器之间的数据传输。这使得设计更加简洁,也更为紧凑。Java Persistence 中的entity bean不同于EJB2.1中的entity bean。应用程序的代码可以直接与entity bean class打交道,而且不用像EJB session bean那样,通过一个组件接口来与entity交互。

11、与旧版本的EJB规范不同,在Java Persistence中,entity bean和Entity Manager不要求必须使用应用服务器。你可以在单元测试和Java应用程序中使用Java Persistence,就像使用任何别的Java库一样。 Message-Driven BeansMessage-driven bean处理异步消息的EJB。Message-driven bean是用来整合其他应用系统的,这些系统和EJB应用一起工作。需要访问EJB应用的Java应用或遗留系统可以通过JMS向message-driven bean发送消息。由这些bean来处理消息,并利用其他的entity

12、 bean和session bean来执行必要的任务。 在许多场合下,JMS-MDB扮演着与stateless session bean同样的角色:它们管理着entity bean和session bean的任务流。这些任务是由应用系统利用JMS发送的异步消息来发起的。与session bean调用其组件接口的业务方法以做出响应。因为消息是异步的,所以发送消息的客户端就不用期望有回复了。客户端简单的将消息发送,然后便可将其抛在脑后。 异步通信除了支持基于 RMI 的分布式业务对象,Enterprise JavaBeans 还支持异步通信。一个异步通信系统允许两个或多个应用以消息的形式交换信息。

13、在这里,消息(message)是一个携带业务数据和网络路由包头(network routing header)的自包含数据包(self-contained package)。包含在消息中的业务数据,根据业务场景可以是任何内容,并且时常包含有关业务性事务的信息。在企业系统中,消息用于通知一个应用系统中的某一事件,或是在其他系统内发生的事件。异步通信使用面向消息的中间件(message-oriented middleware, MOM)可以在网络上将异步消息从一个应用传送到另一个应用。MOM 产品确保消息正确地分布于应用系统间。此外,MOM通常还为需要可靠的交换大量消息的企业提供容错、负载均衡、可

14、伸缩,以及事务支持。Enterprise JavaBeans 将 MOM 的功能集成到其组件模型中。该集成扩展了 EJB 平台,因而它同时支持 RMI 和异步消息。EJB 3.0 借助 Java Message Service(JMS)和一个被称作message-driven bean 的新型组件来支持异步消息。 Java Message Service虽然每个 MOM 厂商各自实现自己的网络协议,路由和管理设施,但是不同 MOM 为开发者所提供的 API,其基本语义是相同的。正是 API 的相似性使得 Java Message Service(JMS)成为可能。JMS 是一组厂商无关(ven

15、dor-agnostic)的 Java API,可以用于许多不同的 MOM 厂商。JMS 与 JDBC 非常类似,应用程序开发者能够重复使用同样的 API 来访问许多不同的系统。如果厂商提供了 JMS 兼容服务提供程序,我们就可以使用 JMS API 来向其发送消息,并且接收来自该提供商的消息。 JCA 1.5在 EJB 2.1 中,借助新的 Java EE Connector Architecture(JCA 1.5),message-driven bean向其他协议的扩展成为了可能。该规范定义了一个用于和企业信息系统交互的可移植的编程模型。在 Java EE 中使用 JCA 就如同在计算机

16、硬件中使用 USB。Web Services web service 代表了分布计算领域里最近的潮流。尽管 web service 这一术语已经广为流传,但是要形成具体化的定义却比较困难,因为在最高层面上,web service 并非专属于任何特定技术或平台。 SOAPWSDLUDDIXML部署描述文件和JAR文件注解允许开发人员在bean class文件中直接制定数据库映射用元数据。Java Persistence规范允许你在一个叫做映射文件(mapping file)的XML部署描述文件中定义bean到数据库的映射。该XML映射文件可以用来取代bean class的注解。如果bean cl

17、ass的注解早已存在,那么该映射文件能够覆盖这些注解,或是提供附加的元数据。XML映射文件的优先级总是高于任何bean class的注解。一旦定义很好XML部署描述文件和entity bean class,你必须将它们全部打包进一个Java Archive(JAR)文件里 Session Bean的开发Session BeanSession bean可分为两种基本类型:stateless和stateful。Stateless session bean是一组相关服务的集合,每个服务由一个方法来表示。Stateless session bean不维护任何介于两次方法调用间的状态。当你调用state

18、less session bean的某个方法时,它会执行该方法并返回结果,既不了解也不关心前后还有哪些调用请求。因此,可以将stateless session bean理解为一组子程序(procedure)或批处理程序(batch progr。am),它们根据传的参数执行请求,然后返回结果。Session BeanStateful session bean是客户端应用程序在服务器端的延续。它代表客户端执行各项任务,并维护着与客户端的会话状态。之所以被称为会话状态是因为,它们代表了stateful session bean和客户端之间的一个持续的会话。调用stateful session bea

19、n的方法,可以从会话状态中读取数据,也可以向其中写入数据,这些数据在所有方法调用之间都是共享的。依赖于特定的EJB厂商,stateful session bean可能会有一个超时期(timeout period)。如果客户端在stateful bean超时前没有对其进行任何调用,bean实例就会被容器自动销毁,与之关联的EJB object引用也会随之失效。这可以避免stateful session bean在客户端关闭后很久才被销毁的情况。我们不希望与此类客户端相关联的stateful session bean始终占据着服务器。除了超时以外,客户端也可以通过调用bean的remove方法明确

20、将其移除。Session Bean由于stateless session bean不保存任何会话状态,并且不是专门为某个客户端提供服务,因而它可以在服务器端驻留更长的时间。只要一个stateless session bean方法调用完成,它就可以被重新分派,为新的客户端提供服务。Stateless session bean也可能存在一个超时期,同样也可以被客户端强制移除,但是其效果与stateful session bean有所不同。超时或移除操作只是简单地让该客户端指向EJB object的引用失效;而bean实例并不会被销毁,它可以继续为其他客户端请求提供服务。Stateless sess

21、ion bean具有很好的性能,并且相对而言比较容易开发。 同样,由于stateless bean不保存任何会话状态,因此也就不需要钝化或激活,这进一步降低了切换的开销。简言之,stateless session bean是轻量而快速的。Stateless Bean这些限制并不意味着stateless session bean不能拥有实例变量,或者维护内部状态。你大可以利用实例变量来跟踪bean的调用次数,或保存调试用数据。你还可以利用实例变量来保存对外部资源的引用,例如:用于日志记录的uRL连接,用于信用卡验证的外部EJB引用,或是其他任何有用的资源。因此,任何保存于实例变量中的数据都应该是

22、“普适性”的。 报表生成、批处理,或者像信用卡验证这样的无状态服务可以使用stateless session bean来实现。 业务接口 一个stateless session bean拥有一个或多个业务接口(business interface)。 业务接口可以是远程接口,也可以是本地接口,但是不能二者兼备。远程业务接口可以接受来自远程客户端的方法调用。当客户端调用session bean的远程接口方法时,无论客户端运行于bean所在的同一JVM,还是网络中的另一台机器,EJB容器都将对参数和返回值进行值拷贝。这就是远程接口的call-by-value语义。本地接口只用于session be

23、an所在的JVM。调用本地接口不会引起参数和返回值的值拷贝。因此,我们称本地接口遵循所谓的call-by-reference语义。应用程序异常 任何远程接口或本地接口都可以抛出应用程序异常(application exception)。应用程序异常用于描述业务逻辑错误。应用程序异常对客户端而言应该是有意义的,它提供一种标示错误的简明手段。EJBException表明容器在处理一个业务接口调用时遇到了问题。由于EJBException是unchecked exception(继承自java1angRuntimeException),因此即便你不捕获它也不会产生编译错误。不过在某些情况下,捕获EJ

24、BException不失为一个良策;而其他情况下,则应让它继续传播下去。由于应用程序异常会被传播到作为调用方的客户端,因而此类异常中的任何实例变量都必须能够被序列化。而非应用程序异常则总会被包装为EJBException。 SessionContextSessionContext对象被作为Bean实例与EJB容器交互的接口。Session bean可以通过它获取到方法调用的上下文信息,也可以快速访问各种EJB服务。你可以通过SessionContext获取诸如当前是哪个用户在调用EJB之类的信息。Sessioncontext.getBusinessObject()方法返回一个指向当前EJB的引

25、用,它可以供其他客户端调用,作用等同于Java中的this指针。 Session Context方法/ security methods public java.security.Principal getCallerPrincipal( ); public boolean isCallerInRole(java.lang.String roleName); / transaction methods public javax.transaction.UserTransaction getUserTransaction( ) throws java.lang.IllegalStateExcep

26、tion; public boolean getRollbackOnly( ) throws java.lang.IllegalStateException; public void setRollbackOnly( ) throws java.lang.IllegalStateException; Stateless Bean生命周期 Session BeanStateful session beanStateful session bean维护着会话状态,也就是说:bean class的实例变量可以在不同的方法调用间维护特定于某个客户端的数据。这将使得方法间的彼此依赖成为可能:如果某个方法

27、调用修改了bean的状态,其后的方法调用也会受到影响。正因为如此,来自客户端的每次方法调用都必须由同一个实例来处理(至少概念上是如此),从而,两次方法调用之间的实例状态变化是可预期的。相反,stateless session bean并不在方法调用间维护与客户端相关的数据,因而任何实例都可以用来处理来自任何客户端的任何方法调用请求。Stateful session beansession bean与其他类型的bean最大的不同之处在于它是不使用实例池的。Stateful bean 在其整个生命周期中只服务于一个客户端,因此对实例进行交换或池化都是不可能的。当它们闲置时,stateful ses

28、sion bean的实例会被容器简单地从内存中移除。EJB object仍然会与客户端保持连接,但是bean实例已经无法被引用到。并且,这些bean实例会在系统空闲期间被垃圾收集器彻底清除。这意味着,每个stateful bean在移除之前都必须被钝化,这可以保证会话状态被有效的保存。从而,当EJB object被重新激活时,会话状态可以再次恢复。激活机制 stateful session bean会在不同的方法调用之间维护会话状态会话状态的完整性需要得到保障。不同于stateless session bean和message-driven bean,stateful session bean

29、使用激活而不是实例池来降低资源的消耗。当EJB服务器需要节省资源时可以从内存中收回stateful session bean。收回stateful session bean时,bean会释放它所占有的内存资源,并将其所保持的会话状态序列化到辅助存储器中。若此时客户端对该EJB对象再次发出请求,EJB容器会重新实例化一个stateful session bean的实例,并从辅助存储器中将之前的状态恢复。钝化钝化(passivation)是解除stateful bean实例与相关EJB对象间的关联,并保存其状态的一种操作。钝化的过程要求bean实例的状态,根据其所关联的EJB对象,被保存起来。当b

30、ean被钝化以后,我们就可以安全地将它的实例从EJB对象和内存中移除。然而客户端并不了解钝化的整个过程,它使用的是bean的远程引用,该远程引用是由EJB的存根代理实现的,因此客户端不直接与bean的实例进行通信。于是,即使在bean被钝化以后,EJB容器仍然可以维护客户端与EJB对象的连接。激活激活bean的操作则是根据其所关联的EJB对象将bean实例的状态重新恢复。当调用钝化了的EJB对象的方法时,容器会自动创建一个新的实例,并按照钝化期间保存的内容逐一设置数据成员。然后,EJB对象会像往常一样将方法调用委托给这个bean实例。 Stateful bean的生命周期 Stateful S

31、ession Bean和Extended Persistence Context当persistence context被标记为EXTENDED时,查询所得的entity将一直保持托管状态,并会被关联于session bean的EntityManager。在这种情况下,updateAddress()方法会变得简单一些,因为我们不再需要EntityMangermerge()方法了。当任何事务性方法被调用时,stateful bean中的所有extended persistence context都会被自动注册到事务中去。 Entity Bean实体Bean一个实体Bean 由实体类和persis

32、tence.xml 文件组成。persistence.xml 文件在Jar 文件的META-INF 目录。persistence.xml 文件指定实体Bean 使用的数据源及EntityManager 对象的默认行为java:/DefaultMySqlDSpersistence-unitpersistence-unit 节点可以有一个或多个,每个persistence-unit 节点定义了持久化内容名称、使用的数据源名称及Hibernate 属性。name 属性用作设置持久化名称。jta-data-source 节点用作指定实体Bean 使用的数据源名称。如果hibernate.hbm2ddl

33、.auto的值设为create-drop,在实体Bean 发布及卸载时将自动创建及删除相应数据库表(注意:Jboss 服务器启动或关闭时会引发实体Bean 的发布及卸载)JBoss数据源的配置Jboss有一个默认的数据源DefaultDS,他使用Jboss内置的HSQLDB数据库。实际应用中你可能使用不同的数据库,如MySql、MsSqlServer、Oracle等。各种数据库的数据源配置模版你可以在Jboss安装目录docsexamplesjca 目录中找到,默认名称为:数据库名+ -ds.xml 。实体Bean 发布前的准备工作1. 配置数据源并放置在jboss 安装目录/server/a

34、ll/deploy 目录,把数据库驱动Jar 包放置在Jboss 安装目录serveralllib 目录下,放置后需要重启Jboss服务器。如果数据源已经存在就不需要配置。2. 配置persistence.xml文件,在文件中指定使用的源据源及各项参数。3. 把实体类和persistence.xml文件打成Jar,persistence.xml 放在jar 文件的META-INF目录Entity BeanCabin bean class 被标注javax.persistence.Entity 和javax.persistence.Table。注解Entity 告知 persistence pr

35、ovider,这是一个映射到数据库的实体类,并且可以受管于 EntityManager 服务。注解Table 则告知 EJB 容器,bean class 应当被映射到哪一张数据库表。Bean class 实现了 java.io.Serializable 接口,但这并非是必须的。假如实体类实现了 Serializable,就可以用作 session bean 中远程接口方法的参数和返回值。这使你能够将同一个类既用于持久化,又用于数据传输。ColumnColumn注释定义了映射到列的所有属性,如列名是否唯一,是否允许为空,是否允许更新等,他的属性介绍如下:name: 映射的列名。如:映射Perso

36、n表的PersonName列,可以在name属性的getName 方法上面加入Column(name = PersonName),如果不指定映射列名,容器将属性名称作为默认的映射列名。unique: 是否唯一nullable: 是否允许为空length: 对于字符型列,length属性指定列的最大字符长度insertable: 是否允许插入updatable: 是否允许更新columnDefinition: 定义建表时创建此列的DDLsecondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字。Column(name = PersonName,nu

37、llable=false,length=32)IdId 注释指定personid属性为表的主键,它可以有多种生成方式:TABLE:容器指定用底层的数据表确保唯一。SEQUENCE:使用数据库的SEQUENCE 列来保证唯一IDENTITY:使用数据库的INDENTIT列来保证唯一AUTO:由容器挑选一个合适的方式来保证唯一NONE:容器不负责主键的生成,由调用程序来完成。GeneratedValue注释定义了标识字段的生成方式,本例personid的值由MySQL数据库自动生成。EntityManagerEntityManager 是由EJB容器自动地管理和配置的,不需要用户自己创建,他用作操

38、作实体Bean。在类中并没有看到对EntityManager em进行赋值,后面却可以直接使用他。这是因为在实体Bean加载时,容器通过PersistenceContext注释动态注入EntityManager 对象。如果persistence.xml文件中配置了多个不同的持久化内容。你需要指定持久化名称注入EntityManager 对象,可以通过PersistenceContext注释的unitName属性进行指定,例:PersistenceContext(unitName=foshanshop)EntityManager em;如果只有一个持久化内容配置,不需要明确指定。托管与非托管实体

39、在进一步讨论 entity manager 服务之前,我们需要更加深入地理解实体对象实例的生命周期。一个 entity bean 实例或者受 entity manager 托管(也称为 attached),或者不受其托管(也称为 detached)。若 entity bean 与 EntityManager相关联,则 EntityManager 会跟踪实体的状态变更,并在 entity manager 决定对实体状态进行 flush 操作的时候,将这些变更保存到数据库中。一旦实体被解除了关联,它就不再受托管了。Entity manager 不会对任何解除关联的实体做状态变更的跟踪。Persis

40、tence contextPersistence context 是由一组受托管的实体对象实例所构成的集合。它受 entity manager 的管理。Entity manager 追踪 persistence context 中所有对象的修改和更新情况,并根据指定的 flush 模式(本章稍后会做讨论)将这些修改保存到数据库中。一旦 persistence context被关闭,所有实体对象实例都会脱离EntityManager而成为非托管对象。对象一旦从persistence context 中脱离,就不再受 entity manager 管理了,任何对此对象的状态变更也将不会被同步到数据

41、库。一旦persistence context被关闭,所有的实体对象实例都会脱离entity manager 而成为非托管对象。Java Persistence 中有两种类型的 persistence context,分别是 transaction-scoped persistence context 和 extended persistence context。Transaction-scoped persistence context有的persistence context可能只在事务范围内存在,它们会在事务结束后被关闭,这样的persistence context 被称作 transa

42、ction-scoped persistence context。当事务结束时,transaction- scoped persistence context 将被销毁,而所有的托管实体对象实例也将处于游离状态(detached)。只有受应用服务器管理的 persistence context 才可以是事务范围的。换言之,只有标注了PersistenceContext 注解(或是其 XML 的等价描述)的 EntityManager实例才可以是事务范围的。Extended persistence context 我们也可以将 persistence context配置成超出事务的范围,我们称之

43、为 extended persistence context。与 extended context 相关联的实体对象实例会一直保持托管状态,甚至在事务提交之后也是如此。在某些场合下,这一特性极为有用。例如,你想保持与数据库的会话,又不希望使用长事务(long-running transaction),因为长事务会一直占用像 JDBC 连接、数据库锁这样的宝贵系统资源。Extended persistence context 可以由应用代码自行创建和管理。 游离实体(Detached entities)当 transaction scope persistence context 或 exten

44、ded persistence context 结束之后,实体的实例就会不受托管而处于游离状态。游离实体的一个值得注意的特征是,它可以被序列化并通过网络发送给远程客户端。客户端可以修改这些经过序列化的对象实例,并将它们发送回服务器,服务器再将客户端的修改重新合并到数据库中。这与 EJB 2.1 的实体模型有很大的不同。在 EJB 2.1 中,实体是始终受容器管理的,使用entity bean 的应用程序总要带一个指向 entity bean 的代理(译注:proxy,即远程接口或本地接口);而在 EJB 3.0 中,你是直接与普通 Java 类的具体实例打交道的。 获取 EntityManag

45、er 我们可以通过 EntityManagerFactory 来创建和获得 EntityManager。在 Java SE 环境中,你必须使用 EntityManagerFactory 来创建 EntityManager 的实例,在 Java EE 中则还有其他选择。package javax.persistence;public interface EntityManagerFactory EntityManager createEntityManager(); EntityManager createEntityManager(java.util.Map map); void close(

46、); boolean isOpen();与 Java SE 相比,在 Java EE 中获取 EntityManagerFactory 要更为容易一些。通过使用javax.persistence.PersistenceUnit 注解,EJB 容器会将 EntityManagerFactory 的实例直接注入或通过 setter 方法注入到 EJB 的数据成员中。EntityManagerpersist()方法 entityManager.persist(cust); find()和 getReference()方法 public interface EntityManager T find(C

47、lass entityClass, Object primaryKey); T getReference(Class entityClass, Object primaryKey); getReference()方法与find()方法的不同之处在于:如果在数据库中找不到相应的实体,getReference()方法将抛出javax.persistence.EntityNotFoundException异常;并且该方法并不保证返回实例的内部状态会被初始化。persistence context 的不同而有所不同:若 EntityManager 是 transactionscoped persist

48、ence context,则会返回游离对象;而若是 extended persistence context,则返回托管对象。 Entity Manager查询Query createQuery(String queryString);Query createNamedQuery(String name);Query createNativeQuery(String sqlString);Query createNativeQuery(String sqlString, Class resultClass);Query createNativeQuery(String sqlString, S

49、tring resultSetMapping);更新 一旦你调用了 find(),getReference(),或创建并执行了一次查询,所得的 entity bean实例在 persistence context 关闭前仍将处于托管状态。在此期间,你可以像其他对象那样随便更改 entity bean 实例的状态,任何更改都将被自动(取决于 flush 模式)或手工(通过调用 flush()方法)地同步到数据库中。合并实体 在 Java Persistence 中,你可以使用 EntityManager 的 merge()方法,将游离实体的状态变更合并到数据库中。 Entity Manager删

50、除实体调用EntityManager.remove()可以将实体从数据库中删除。不过,remove()方法并不立即生效,而是在 EntityManager 决定执行 flush 操作时,根据定义好的 flush 规则才会执行 SQL DELETE 操作。refresh()如果发现当前受托管的实体并非数据库中的最新数据,你可以调用 EntityManager. refresh()方法。refresh()方法会根据数据库的情况刷新内存中实体的状态,同时覆盖对实体所做的任何修改。contains()方法与 clear()方法 contains()方法接受实体实例作为参数,如果该对象实例目前正受 pe

51、rsistence context 管理,则返回 true。若该参数并非实体类型,则会抛出 IllegalArgumentException 异常。你可以使用 EntityManager.clear()方法将 persistence context 中所有的托管实体都变成游离对象。需要注意的是,一旦你调用了 clear()方法,对实体所做的任何修改都将被丢弃。因此,使用 clear()时需要格外小心。在调用 clear()之前,先调用 flush()方法以免丢失更改实为明智之举。flush()方法和 FlushModeType 调用persist(),merge(),remove()方法之后,

52、这些更改操作只有在EntityManager 决定执行 flush 操作时才会被同步到数据库中。你也可以在任何时候通过调用flush()方法做强行同步。缺省情况下,flush操作会在相关查询执行之前和事务提交之时自动执行(一些低效的 Java Persistence 实现甚至可能会在任何查询执行之前都做 flush操作)。但需注意的是,与一般查询不同,调用 find()和 getReference()方法并不会引起 flush。这是因为通过主键来查询实体是不会受任何更新操作的影响的。可以通过枚举类型 javax.persistence.FlushModeType 来控制和修改这一默认行为。pu

53、blic enum FlushModeType AUTO, COMMITAUTO 是前述的默认行为。COMMIT 则表示,仅当事务提交时才对更改做 flush 操作,而在任何查询执行之前都不会引发flush操作。你可以通过调用setFlushMode()方法来指定 EntityManager 的 FlushModeType。 getDelegate()getDelegate() 方法允许你获 得一个指向底层persistence provider对象引用 , 该persistence provider 实现了EntityManager 接口。大多数厂商都提供了针对 EntityManager接

54、口的 API 扩展,为了使用这些扩展功能,你可以将获取到的 delegate 对象强制类型转换为厂商的私有接口。虽然从理论上讲,你应该可以编写出厂商无关的代码。但实际上,多数厂商都提供了大量针对Java Persistence的扩展,你可以在应用程序中充分利用这些功能。而 getDelegate()方法提供了一种获取并使用厂商专有 API 的途径。createQuery()Query query = em.createQuery(select p from Person p where p. name=黎明);List result = query.getResultList();Iterat

55、or iterator = result.iterator();while( iterator.hasNext() )/处理PersonQuery query = em.createQuery(update Person as p set =?1 where p. personid=?2);query.setParameter(1, “黎明” );query.setParameter(2, new Integer(1) );int result = query.executeUpdate(); /影响的记录数Query query = em.createQuery(delete

56、from Person);int result = query.executeUpdate(); /影响的记录数Message-Driven BeanJMS和Message-Driven Bean所有EJB 3.0开发商都必须提供一个JMS provider的实现。大多数开发商都应该在EJB容器中内置一个JMS provider,并通过JCA接入其他类型的JMS provider。但是不管开发商是自己提供JMS provider还是允许你整合其他provider,JMS provider对于Message-Driven bean而言绝对是必须的。 JMSJMS是一套用于访问企业消息系统的开发商

57、中立的API。企业消息系统(也就是面向消息的中间体)可以协助应用软件通过网络进行消息交互。JMS在其中扮演的角色于JDBC很相似:正如JDBC提供了一套用于访问各种不同关系数据库的公共API,JMS也提供了独立于特定厂商的企业消息系统访问方式。JbossMQ,IBM的MQSerles、BEA的WebLogic JMS service、Sun Microsystems的Sun ONE Message Queue和Sonic的SonicMQ。 JMS使用JMS的应用程序被称为JMS客户端,处理消息的路由与传递的消息系统被称为JMS provider,而JMS应用则是由多个JMS客户端和一个JMS

58、provider(通常是一个)构成的业务系统。发送消息的JMS客户端被称为生产者(producer),而接收消息的JMS客户端则被称为消费者consumer)。同一JMS客户端既可以是生产者也可以是消费者。ConnectionFactory和Topic 为了发送JMS消息,我们需要一个指向JMS provider的连接和一个消息目标地址。使用JMS连接工厂(JMS connection factory) 可以获得JMS provider 连接;而消息目标地址则可以由一个Topic 对象来表示。我们可以利用javax.annotation.Resource注解直接将连接工厂和Topic 对象注入

59、到TravelAgent EJB的数据成员中。Resource(mappedName = “ConnectionFactoryNameGoes”)Private ConnectionFactory connectionFactory;Resource(mappedName = “TicketTopic”)Private Topic topic ;TopicTopic对象代表了独立于具体网路结构的消息目的地址。在JMS中,消息并不是直接发送给应用程序,而是发送到主题(topic)或队列(queue)中。主题类似于邮件列表或新闻组,任何获得许可的应用程序都可以接收来自主题的消息或向主题发送消息。如

60、果JMS客户端受到了来自某个主题的消息,我们就称该客户端订阅了该主题。JMS通过目标地址实现了应用程序间的消息传递,消息目标地址就像一个虚拟通道,JMS利用它对应用程序进行了解耦。 Connection & Session拥有了Connection,你就可以用它来创建Session对象。Session对象允许你将一系列发送和接收消息的操作组织在一起。 Session对象采用单线程模型,因此你不能在多个线程中并发的访问同一个Session对象。创建Session对象的线程通常也就是使用该Session对象的生产者和消费者所在的线程 createSession()方法有两个参数。createSes

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论