J2EE学习笔记知识点精粹(servlet,websoket,webservice,Jax-rs,EJB,JPA)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

说明:在编程中我们会在某个类、方法或变量前面加上@x,来表明这个类、方法或变量具有x属性。

1.Servlet
1).Servlet 是什么?
Java Servlet 是运行在Web 服务器或应用服务器上的程序,它是作为来自Web 浏览器或其他HTTP 客户端的请求和HTTP 服务器上的数据库或应用程序之间的中间层。

2).Servlet 有以下几点优势
(1).性能明显更好。

(2).Servlet 在Web 服务器的地址空间内执行。

这样它就没有必要再创建一个单独的进程来处理每个客户端请求。

(3).Servlet 是独立于平台的,因为它们是用Java 编写的。

(4).服务器上的Java 安全管理器执行了一系列限制,以保护服务器计算机上的资源。

因此,Servlet 是可信的。

(5).Java 类库的全部功能对Servlet 来说都是可用的。

它可以通过sockets 和RMI 机制与applets、数据库或其他软件进行交互。

3).Servlet 架构
过程为:
(1) 客户端发送请求至服务器端;
(2) 服务器将请求信息发送至Servlet;
(3) Servlet 生成响应内容并将其传给服务器。

响应内容动态生成,通常取决于客户端的请求;
(4) 服务器将响应返回给客户端。

4).servlet生命周期
(1).客户端请求该Servlet;
(2).加载Servlet 类到内存;
(3).实例化并调用init()方法初始化该Servlet;
(4).service()(根据请求方法不同调用doGet() 或者doPost(),此外还有doGet()、doPut()、doTrace()、doDelete()、doOptions());
(5).destroy()。

5).看一下老师ppt和教程(这个很不错/holandstone/article/details/16844957)
想学的更好就看servlet-api.chm
2.web socket
(1).web socket:是HTML5一种新的协议。

它实现了浏览器与服务器全双工通信(full-duplex)。

(2).websocket的优点
以前我们实现推送技术,用的都是轮询,在特点的时间间隔有浏览器自动发出请求,将服务器的消息主动的拉回来,在这种情况下,我们需要不断的向服务器发送请求,然而HTTP request 的header是非常长的,里面包含的数据可能只是一个很小的值,这样会占用很多的带宽和服务器资源。

会占用大量的带宽和服务器资源。

WebSocket API最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息。

在建立连接之后,服务器可以主动传送数据给客户端。

此外,服务器与客户端之间交换的标头信息很小。

WebSocket并不限于以Ajax(或XHR)方式通信,因为Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息;
WebSocket的握手过程主要有一下两个步骤:
1).WebSocket客户端首先发起一个连接请求。

请求数据中包括服务器的IP和端口、以及客户端随机生成的Key等。

2).服务器端根据客户端的key生成密钥,并将密钥返回给客户端,握手成功。

由于WebSocket的连接本质是一个TCP连接,所以与传统的浏览器轮询方式比,这种方式对于数据传输的稳定性和数据量大小方面都有一定的优势。

而很多实验也证明在流量比较大的情况下,使用WebSocket也具有很大的性能优势。

(3).如何使用websocket(分客户端和服务器端,两个启动后保持连接才能即时通信,当然了系统性能会降低)
客户端
在支持WebSocket的浏览器中,在创建socket之后。

可以通过onopen,onmessage,onclose即onerror四个事件实现对socket进行响应.
一个简单是示例:
var wsServer = 'ws://localhost:8888/Demo';
var websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) { onOpen(evt) };
websocket.onclose = function (evt) { onClose(evt) };
websocket.onmessage = function (evt) { onMessage(evt) };
websocket.onerror = function (evt) { onError(evt) };
function onOpen(evt) {
console.log("Connected to WebSocket server.");
}
function onClose(evt) {
console.log("Disconnected");
}
function onMessage(evt) {
console.log('Retrieved data from server: ' + evt.data);
}
function onError(evt) {
console.log('Error occured: ' + evt.data);
}
1).var ws = new WebSocket(“ws://localhost:8888/Demo”);
申请一个WebSocket对象,参数是需要连接的服务器端的地址,同http协议使用http://开头一样,WebSocket协议的URL使用ws://开头,另外安全的WebSocket协议使用wss://开头。

ws.send(“hello”)
用于叫消息发送到服务端
2).ws.onopen = function() { console.log(“open”)};
当websocket创建成功时,即会触发onopen事件
3).ws.onmessage = function(evt) { console.log(evt.data) };
当客户端收到服务端发来的消息时,会触发onmessage事件,参数evt.data中包含server传输过来的数据
4).ws.onclose = function(evt) { console.log(“WebSocketClosed!”); };
当客户端收到服务端发送的关闭连接的请求时,触发onclose事件
5).ws.onerror = function(evt) { console.log(“WebSocketError!”); };
如果出现连接,处理,接收,发送数据失败的时候就会触发onerror事件
我们可以看出所有的操作都是采用事件的方式触发的,这样就不会阻塞UI,使得UI有更快的响应时间,得到更好的用户体验。

服务端
这里我使用的是tomat 7.0和eclipse4.2
在tomcat下使用websocket首先需要导入相关的jar
tomcat7提供的与WebSocket相关的类均位于包org.apache.catalina.websocket之中(包org.apache.catalina.websocket的实现包含于文件catalina.jar之中
这里我们把tomcat的全部导入就行了
在build path->configure build path->librarise->add library->server runtime->apache tomcat v7.0 image
同时需要import以下包
import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WsOutbound;
import org.apache.catalina.websocket.WebSocketServlet;
需要两个类
第一个用于处理websocket请求
第二个用于处理每一次具体的WebSocket任务
第一个类
public class SocketServer extends WebSocketServlet {
private static final long serialVersionUID = 1L;
//……
@Override
protected StreamInbound createWebSocketInbound(String arg0,
HttpServletRequest arg1) {
// TODO Auto-generated method stub
return new ChatWebSocket(users);
}
}
这个Servlet继承自WebSocketServlet,实现createWebSocketInbound方法。

该方法返回第二个类的实例。

第二个类(传统的非注解开发)
public class ChatWebSocket extends MessageInbound {
@Override
protected void onTextMessage(CharBuffer message) throws IOException {
}
@Override
protected void onOpen(WsOutbound outbound) {
}
@Override
protected void onClose(int status) {
}
@Override
protected void onBinaryMessage(ByteBuffer arg0) throws IOException {
}
//其余略
}
//文本消息响应
protected void onTextMessage(CharBuffer message) throws IOException { }
//二进制消息响应
protected void onBinaryMessage(ByteBuffer arg0) throws IOException { }
//
sendObject(envelope)
//数据流
getSendStream() –Java InputStream
getSendWriter() –Java Writer
//建立连接的触发的事件
protected void onOpen(WsOutbound outbound) { }
//关闭连接时触发的事件
protected void onClose(int status) { }
注解开发:在类上加@ServerEndpoint,在每个方法上面写对应的注解就可以了
@WebSocketEndpoint
Class level annotation for websocket server endpoint
@WebSocketClient
Class level annotation for websocket client endpoint
@WebSocketOpen
Method level annotation signifies a method to be called whenever a new client connects to this endpoint
@WebSocketClose
Method level annotation signifies a method to be called whenever a new client is about to disconnects from this endpoint @WebSocketMessage
Method level annotation signifies a method to be called whenever an incoming message is received
例:
@ServerEndpoint("/chat")
public class ChatServer {
@OnMessage
public String receiveMessage(String message) {
//. . .
}
}
(4).Core WebSocket methods流程图
注:websocket在信息传递过程支持加密、解密功能(Encode/Decode)
(5).WebSockets 的应用场景
1.社交订阅
对社交类的应用的一个裨益之处就是能够即时的知道你的朋友正在做什么。

虽然听起来有点可怕,但是我们都喜欢这样做。

你不会想要在数分钟之后才能知道一个家庭成员在馅饼制作大赛获胜或者一个朋友订婚的消息。

你是在线的,所以你的订阅的更新应该是实时的。

2.多玩家游戏
网络正在迅速转变为游戏平台。

在不使用插件(我指的是Flash)的情况下,网络开发者现在可以在浏览器中实现和体验高性能的游戏。

无论你是在处理DOM元素、CSS动画,HTML5的canvas或者尝试使用WebGL,玩家之间的互动效率是至关重要的。

我不想在我扣动扳机之后,我的对手却已经移动位置。

3.协同编辑/编程
我们生活在分布式开发团队的时代。

平时使用一个文档的副本就满足工作需求了,但是你最终需要有一个方式来合并所有的编辑副本。

版本控制系统,比如Git能够帮助处理某些文件,但是当Git发现一个它不能解决的冲突时,你仍然需要去跟踪人们的修改历史。

通过一个协同解决方案,比如WebSocket,我们能够工作在同一个文档,从而省去所有的合并版本。

这样会很容易看出谁在编辑什么或者你在和谁同时在修改文档的同一部分。

4.点击流数据
分析用户与你网站的互动是提升你的网站的关键。

HTTP的开销让我们只能优先考虑和收集最重要的数据部分。

然后,经过六个月的线下分析,我们意识到我们应该收集一个不同的判断标准——一个看起来不是那么重要但是现在却影响了一个关键的决定。

与HTTP请求的开销方式相比,使用Websocket,你可以由客户端发送不受限制的数据。

想要在除页面加载之外跟踪鼠标的移动?只需要通过WebSocket连接发送这些数据到服务器,并存储在你喜欢的NoSQL数据库中就可以了(MongoDB是适合记录这样的事件的)。

现在你可以通过回放用户在页面的动作来清楚的知道发生了什么。

5.股票基金报价
金融界瞬息万变——几乎是每毫秒都在变化。

我们人类的大脑不能持续以那样的速度处理那么多的数据,所以我们写了一些算法来帮我们处理这些事情。

虽然你不一定是在处理高频的交易,但是,过时的信息也只能导致损失。

当你有一个显示盘来跟踪你感兴趣的公司时,你肯定想要随时知道他们的价值,而不是10秒前的数据。

使用WebSocket可以流式更新这些数据变化而不需要等待。

6.体育实况更新
现在我们开始讨论一个让人们激情澎湃的愚蠢的东西——体育。

我不是运动爱好者,但是我知道运动迷们想要什么。

当爱国者在打比赛的时候,我的妹夫将会沉浸于这场比赛中而不能自拔。

那是一种疯狂痴迷的状态,完全发自内心的。

我虽然不理解这个,但是我敬佩他们与运动之间的这种强烈的联系,所以,最后我能做的就是给他的体验中降低延迟。

如果你在你的网站应用中包含了体育新闻,WebSocket能够助力你的用户获得实时的更新。

7.多媒体聊天
视频会议并不能代替和真人相见,但当你不能在同一个屋子里见到你谈话的对象时,视频会议是个不错的选择。

尽管视频会议私有化做的“不错”,但其使用还是很繁琐。

我可是开放式网络的粉丝,所以用WebSockets getUserMedia API 和HTML5音视频元素明显是个不错的选择。

WebRTC的出现顺理成章的成为我刚才概括的组合体,它看起来很有希望,但其缺乏目前浏览器的支持,所以就取消了它成为候选人的资格。

8.基于位置的应用
越来越多的开发者借用移动设备的GPS功能来实现他们基于位置的网络应用。

如果你一直记录用户的位置(比如运行应用来记录运动轨迹),你可以收集到更加细致化的数据。

如果你想实时的更新网络数据仪表盘(可以说是一个监视运动员的教练),HTTP协议显得有些笨拙。

借用WebSocket TCP链接可以让数据飞起来。

9.在线教育
上学花费越来越贵了,但互联网变得更快和更便宜。

在线教育是学习的不错方式,尤其是你可以和老师以及其他同学一起交流。

很自然,WebSockets是个不错的选择,可以多媒体聊天、文字聊天以及其它优势如与别人合作一起在公共数字黑板上画画...
3.web Service
个人总结:Web Services 就是用WSDL语言描述的,在UDDI注册中心注册的,用户可以通过SOAP协议调用的对外接口(函数)。

Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术。

是:通过SOAP在Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI进行注册。

SOA (面向服务的体系结构):面向服务的体系结构是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。

XML:(Extensible Markup Language)扩展型可标记语言。

面向短期的临时数据处理、面向万维网络,是Soap的基础。

66
Soap:(Simple Object Access Protocol)简单对象存取协议。

是XML Web Service 的通信协议。

当用户通过UDDI找到你的WSDL描述文档后,他通过可以SOAP调用你建立的Web服务中的一个或多个操作。

SOAP是XML文档形式的调用方法的规范,它可以支持不同的底层接口,像HTTP(S)或者SMTP。

WSDL:(Web Services Description Language) WSDL 文件是一个XML 文档,用于说明一组SOAP 消息以及如何交换这些消息。

大多数情况下由软件自动生成和使用。

UDDI (Universal Description, Discovery, and Integration) 是一个主要针对Web服务供应商和使用者的新项目。

在用户能够调用Web服务之前,必须确定这个服务内包含哪些商务方法,找到被调用的接口定义,还要在服务端来编制软件,UDDI是一种根据描述文档来引导系统查找相应服务的机制。

UDDI利用SOAP消息机制(标准的XML/HTTP)来发布,编辑,浏览以及查找注册信息。

它采用XML格式来封装各种不同类型的数据,并且发送到注册中心或者由注册中心来返回需要的数据。

实现一个完整的Web服务包括以下步骤:
◆ Web服务提供者设计实现Web服务,并将调试正确后的Web服务通过Web服务中介者发布,并在UDDI注册中心注册;(发布)
◆ Web服务请求者向Web服务中介者请求特定的服务,中介者根据请求查询UDDI注册中心,为请求者寻找满足请求的服务;(发现)
◆ Web服务中介者向Web服务请求者返回满足条件的Web服务描述信息,该描述信息用WSDL写成,各种支持Web服务的机器都能阅读;(发现)
◆利用从Web服务中介者返回的描述信息生成相应的SOAP消息,发送给Web服务提供者,以实现Web服务的调用;(绑定)◆ Web服务提供者按SOAP消息执行相应的Web服务,并将服务结果返回给Web服务请求者。

(绑定)
Web Service的基本原理
(1) Service Provider采用WSDL描述服务
(2) Service Provider 采用UDDI将服务的描述文件发布到UDDI服务器(Register server)
(3) Service Requestor在UDDI服务器上查询并获取WSDL文件
(4) Service requestor将请求绑定到SOAP,并访问相应的服务。

Tips:WSDL与SOAP
WSDL:Web Service Description Language(Web服务描述语言)。

作用:
(1) 描述服务是什么,服务提供的操作(方法名,方法参数,返回值,数据类型等);
(2) 如何访问该服务→binding
(3) 服务访问的地址→service
Banding:定义Web服务访问采用的协议(SOAP)
SOAP:Simple Object Access Protocol(简单对象访问协议)
4.jax-ws(Java TM API forXML-Based Web Services)是面向资源的
1).基本概述
(1).JAX-WS规范是一组XML web services的JAVA API,JAX-WS允许开发者可以选择RPC-oriented或者message-oriented 来实现自己的web services。

(2).在JAX-WS中,一个远程调用可以转换为一个基于XML的协议例如SOAP,在使用JAX-WS过程中,开发者不需要编写任何生成和处理SOAP消息的代码。

JAX-WS的运行时实现会将这些API的调用转换成为对应的SOAP消息。

(3).在服务器端,用户只需要通过Java语言定义远程调用所需要实现的接口SEI(service endpoint interface),并提供相关的实现,通过调用JAX-WS的服务发布接口就可以将其发布为WebService接口。

(4).在客户端,用户可以通过JAX-WS的API创建一个代理(用本地对象来替代远程的服务)来实现对于远程服务器端的调用。

(5).当然JAX-WS 也提供了一组针对底层消息进行操作的API调用,你可以通过Dispatch 直接使用SOAP消息或XML 消息发送请求或者使用Provider处理SOAP或XML消息。

通过web service所提供的互操作环境,我们可以用JAX-WS轻松实现JAVA平台与其他编程环境(.net等)的互操作。

2).描述了一个SOAP binding的JAX WS从接受到客户端的请求到返回请求给客户端的过程
1,客户端开发者通过URL得到WSDL文件。

(通过HTTP访问可以得到,http://<endpoint-address>?wsdl)
2,客户端根据WSDL的描述,通过HTTP POST发送SOAP消息给服务器端。

3, 服务器端Listener接受到SOAP请求消息,对JAVA来说,通常是一个servlet或者EJB。

Listener把消息转发给Dispatcher,有时候listener和Dispatcher也可能是同一个类。

Dispatcher会把请求消息交给WebService的运行终端。

4,这时候,服务器端会将HTTP request转成服务器端的消息类型,形成javax.xml.ws.handler.MessageContext,并处理SOAP消息的头信息,如mustUnderstand。

5,如果在服务器端配置了handler,会调用handler的handleMessage方法,通常用handler来保存消息,解密或者保证消息到达的顺序。

handler通过在@HandlerChain标注配置,
handlers.xml文件内容为:
<handler-chains xmlns="/xml/ns/javaee">
<handler-chain>
<handler>
<handler-name>WSSOAPHandler</handler-name>
<handler-class>com.cxf.test.WSSOAPHandler</handler-class>
</handler>
</handler-chain>
<handler-chain>
<handler>
<handler-name>WSHandler</handler-name>
<handler-class>com.cxf.test.WSHandler</handler-class>
</handler>
</handler-chain>
</handler-chains>
6,SOAP消息被反序列化为JAVA对象,传到真正的实现业务的类。

7,调用真正的业务方法,执行后利用JAXB注解序列化成SOAP返回消息。

8,如果配置了handler,会调用handler的handleMessage方法。

如果业务方法有异常抛出,把异常转为SOAP fault 消息。

9,Listener通过HTTP把response返回给客户端。

3).
5.Jax-rs(Java TM API forRESTful Web Services)是面向资源的
1).jax-rs基本概念
JAX-RS是JAVA EE6 引入的一个新技术。

JAX-RS即Java API for RESTful Web Services,是一个Java 编程语言的应用程序接口,支持按照表述性状态转移(REST)架构风格创建Web服务。

JAX-RS使用了Java SE5引入的Java标注来简化Web服务的客户端和服务端的开发和部署。

2).jax-rs使用到的标注
@Path,标注资源类或者方法的相对路径
@GET,@PUT,@POST,@DELETE,标注方法是HTTP请求的类型。

@Produces,标注返回的MIME媒体类型
@Consumes,标注可接受请求的MIME媒体类型
@PathParam,@QueryParam,@HeaderParam,@CookieParam,@MatrixParam,@FormParam,分别标注方法的参数来自于HTTP请求的不同位置,例如@PathParam来自于URL的路径,@QueryParam来自于URL的查询参数,@HeaderParam来自于HTTP请求的头信息,@CookieParam来自于HTTP请求的Cookie。

3).看实例代码
6.EJB(Enterprise JavaBean)
4).EJB是什么:
是采用Java语言开发、部署服务器端的分布式组件的标准和框架。

5).为什么用?
(1) 大型的企业级程序分解为分层分布的应用,必须使用EJB;
(2) 构建多层程序架构;
(3) 各层独立,专注自己擅长的领域;
(4) 采用EJB可以不用考虑中间件服务(Middleware Service)
6).EJB开发和调用步骤
(1).开发编译业务接口和Bean类。

(加上@statless/stateful或@local/remote)
(2).打包部署到JNDI服务器。

(配置jndi.properties:gives remote URL and other info)
(3).客户端通过上下文(Context),调用其接口。

例如:InitialContext context = new InitialContext();
InterfaceName bean = (InterfaceName)context.lookup("JNDI-Name");
7).EJB定义了三种Bean,
分别是会话Bean(Session Bean),实体Bean(Entity Bean),消息驱动Bean(MessageDrive Bean)。

Session Bean:a.有状态的:该状态在客户程序和Bean进行会话期间被保持,(激活实现),效率低。

b.无状态的:不为特定的客户程序保持会话状态。

(实例池实现)
Entity Bean:一般实体Bean对应着数据库中的一张表。

MessageDrive Bean:应用程序异步的接收Java消息服务(JMS)的消息。

8).@local和@remote接口(不写时默认为@local)
(1).web层调用app层使用remote接口。

session bena和entity bean之间调用使用的是local接口。

(2).remote接口对性能的影响是很大的。

所以在设计的时候我们应尽量使用local接口,local运行在一个EJB容器的JVM中,remote接口运行在不同的JVM中。

(3).在一般情况下建议两种类型的接口(包括EJBHome 与EJBObject)都生成,尤其是Session Bean,Entity Bean,可以只生成local类型的接口,如果想远程调用你的Entity Bean一般用Session Bean做代理。

(4).如果你不是远程调用EJB的话,使用EJB时建议调用local接口,这样效率高,因为远程调用就意味着建立网络连接,效率必然不如local调用。

9).有状态(stateful)和无状态(stateless)会话bean的本质区别是它们的生命期。

1)有状态会话bean :每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”;一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。

即每个用户最初都会得到一个初始的bean。

生命周期我们可以用web中context去简单认识,比如session、request等。

在这个生命周期内,用户只会得到一个特定的stateful 会话bean。

2)无状态会话bean :bean一旦实例化就被加进会话池中,各个用户都可以共用。

即使用户已经消亡,bean 的生命期也不一定结束,它可能依然存在于会话池中,供其他用户调用。

由于没有特定的用户,那么也就不能保持某一用户的状态,所以叫无状态bean。

但无状态会话bean 并非没有状态,如果它有自己的属性(变量),那么这些变量就会受到所有调用它的用户的影响,这是在实际应用中必须注意的。

bean 的生命周期是由容器决定的
这两种bean的使用场合简析:
1)有状态会话bean:用于跟踪用户数据,它可以在分布式中被缓存和传递,只要生命周期未被销毁(如session会话,前提是此会话bean被session会话管理),那么此bean可以在应用中随时获取,且数据时被同步更新的。

它就像你的“妻子”,你要你还“爱她”,她会随你“一生”
场合:用户登录权限切片控制,购物车等
2)无状态会话bean:这里你需要用servlet的思想去认识它,它就想servlet一样,为上层调用提供服务,并且是线程池的形式存在。

当服务调用结束(如:获取web 服务,查询站点数据统计),无状态会话bean可能被销毁但也能继续存在,取决于线程池饱和度,但它不会为你保存任何和你的调用有“个人私情”的数据。

你就认为他是一个servlet,它是提供共享服务的,它不是“老婆”,更像给你送邮件的“邮递员”,你们直接的交易,只是在你需要的时候,并以及结束。

(例如转账)
7).Session Beans vs.Message-Driven Beans (MDBs)
8).
1.JPA(Java Persistence API)
1).ORM(Object Relational Mapping对象关系映射) Entity是一个POJO,JPA(Java Persistence API)可以使用实体来持久化。

2).JPA的特点
1).JPA是一种标准的持久化机制
2). 在容器内外均可以运行
3). 持久化提供者(Hibernate等)不影响JPA的使用
3).JPA概述
JPA维护一个Persistence Context(持久化上下文),在持久化上下文中维护实体的生命周期。

主要包含三个方面的内容:
1.ORM元数据。

JPA支持annotion或xml两种形式描述对象-关系映射。

2.实体操作API。

实现对实体对象的CRUD操作。

3.查询语言。

约定了面向对象的查询语言JPQL(Java Persistence Query Language)。

4).实体生命周期
1.New,新创建的实体对象,没有主键(identity)值
2.Managed,对象处于Persistence Context(持久化上下文)中,被EntityManager管理
3.Detached,对象已经游离到Persistence Context之外,进入Application Domain
4.Removed, 实体对象被删除
EntityManager提供一系列的方法管理实体对象的生命周期,包括:
1.persist, 将新创建的或已删除的实体转变为Managed状态,数据存入数据库。

2.remove,删除受控实体
3.merge,将游离实体转变为Managed状态,数据存入数据库。

如果使用了事务管理,则事务的commit/rollback也会改变实体的状态。

4.refresh, 从数据库中从新加载实体状态
注:EJB容器中获得EntityManager对象主要有两种方式,即@PersistenceContext注释注入和JNDI方式获得。

org.hibernate javax.persistence说明
cfg.Configuration Persistence读取配置信息
SessionFactory EntityManagerFactory用于创建会话/实体管理器的工厂类
Session EntityManager提供实体操作API,管理事务,创建查询Transaction EntityTransaction管理事务
Query Query执行查询
5).Persistence context 与Entity manager
(1).Persistence context(持久化上下文)
Ø一个持久化单元(Persistence Unit)就是关于一组Entity类的命名配置。

持久化单元是一个静态的概念。

Ø一个持久化上下文(Persistence Context)就是一个受管的Entity实例的集合。

每一个持久化上下文都关联一个持久化单元,持久化上下文不可能脱离持久化单元独立存在。

持久化上下文中的Entity实例就是相关联的持久化单元中的若干Entity的实例。

持久化上下文是一个动态的概念。

Ø一个Entity实例处于受管状态,其实质是:该实例存在于某个持久化上下文中,并且可能被某个EntityManager处理,也因为这个原因,所以我们说一个EntityManager管理一个持久化上下文。

Ø尽管持久化上下文非常重要,但是开发者不直接与之打交道,持久化上下文在应用程序中是透明的,我们需要通过EntityManager间接管理它。

(2).Entity manager(实体管理器)
Ø通过将@PersistenceContext注解标注在EntityManager类型的字段上,这样得到的EntityManager就是容器管理的EntityManager。

由于是容器管理的,所以我们不需要也不应该显式关闭注入的EntityManager实例。

Ø容器管理的EntityManager又细分为两种类型:事务范围(Transaction)的和扩展的(Extended)。

Ø若@PersistenceContext未指定type属性,或者指定为PersistenContextType.TRANSACTION,则表示该EntityManager 是事务范围的;若指定为PersistenContextType.EXTENDED的,则表示该EntityManager是扩展的。

Ø事务范围:事务范围的EntityManager是无状态的,可用在无状态会话Bean和有状态会话Bean中。

ü事务范围的EntityManager依赖于JTA事务,每次调用EntityManager实例的相关方法时,EntityManager会查看是否有某个持久化上下文与当前事务关联,如果有,则使用该持久化上下文;如果没有,则EntityManager将创建一个持久化上下文,并将该持久化上下文与当前事务关联。

当事务结束,则持久化上下文消失。

Ø扩展的:扩展的EntityManager只能用于有状态会话Bean。

ü扩展的EntityManager在有状态会话Bean实例创建的时候创建一个持久化上下文,并且直到该有状态会话Bean销毁,则相应的持久化上下文才被移除。

ü由于在扩展的EntityManager中,每次方法调用都是使用的相同的持久化上下文,所以前一次方法调用时产生的受管实体在下一个方法访问时仍然为受管实体。

6).事务管理
(1).JPA支持本地事务管理(RESOURCELOCAL)和容器事务管理(JTA),容器事务管理只能用在EJB/Web容器环境中。

事务管理的类型可以在persistence.xml文件中的“transaction-type”元素配置。

JPA中通过EntityManager的getTransaction()方法获取事务的实例(EntityTransaction),之后可以调用事务的begin()、commit()、rollback()方法。

(2).Transaction Attributes(事务属性类型)
@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class)
@TransactionAttributeType(TransactionAttributeType.xxx)
用注解@Transactional, 配置TransactionAttributeType.xxx,xxx为以下
Required:如果上下文中已经有事物,则使用当前事务,若无,则启动一个新事物
Mandatory:上下文比如要有事物,若无事物,这抛出异常
RequiresNew:不管上下文是否有事物,启动一个新的事物
Supports:如果上下文中已经有事物,则使用当前事务,若无,则不启动事物
NotSupported:不管上下文是否有事物,从不启动一个事物
Never:不管上下文是否有事物,从不启动一个事物。

如果上下文中有事物,抛出异常
7.JPQL
(1).查询方式
方式一:根据主键查询,使用EntityManager的find方法:find(Class entityClass, Object primaryKey)。

方式二:使用JPQL查询语言。

JPQL是完全面向对象的,具备继承、多态和关联等特性。

使用EntityManager的createQuery 方法:Query createQuery(String qlString)。

相关文档
最新文档