|
若您要直接在Servlet中使用JPA,要記得的是,EntityManager不是Thread-safe,所以切記,不可直接將EntityManager注入Servlet中成為物件成員之一,Servlet被共用存取的情況下,會有資料共用存取的問題。
若您要在Servlet中直接使用JPA,有兩種方式可以進行,一是透過在類別上宣告@PersistenceContext並設定JNDI名稱來查找,
二是透過@PersistenceUnit注入EntityManagerFactory並用其取得EntityManager,前者的方式為
Container-Managed Entity,後者的方式則為Application-Managed EntityManager。
第一個方法若以 第一個 JPA(容器管理) 中的User實體為例,您可以如下撰寫Servlet:
package onlyfun.caterpillar;
import java.io.*;
import java.util.logging.*; import javax.annotation.*; import javax.naming.*; import javax.persistence.*; import javax.rmi.PortableRemoteObject; import javax.servlet.*; import javax.servlet.http.*; import javax.transaction.*;
@PersistenceContext(name="sample/EntityManager", unitName="sample") public class UserAdmin extends HttpServlet { @Resource private UserTransaction ut;
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("name"); String age = request.getParameter("age"); User user = new User(); user.setName(name); user.setAge(new Long(Long.parseLong(age))); response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); EntityManager entityManager = null;
try { InitialContext context = new InitialContext(); Object obj = context.lookup( "java:comp/env/sample/EntityManager"); entityManager = (EntityManager) PortableRemoteObject.narrow(obj, EntityManager.class); ut.begin(); entityManager.persist(user); ut.commit();
} catch (Exception ex) { Logger.getLogger(UserAdmin.class.getName()) .log(Level.SEVERE, null, ex); } finally { entityManager.close(); out.close(); } }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); }
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } }
在您的Web應用程式可存取的Classpath路徑中(例如WEB-INF/classes下),要建立META-INF/persistence.xml:
<?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="sample" transaction-type="JTA"> <jta-data-source>jdbc/sample</jta-data-source> <properties> <property name="toplink.ddl-generation" value="drop-and-create-tables"/> </properties> </persistence-unit> </persistence>
@PersistenceContext的name名稱將作為JNDI查找名稱,從unitName設定得知,實際上查找到的
是<persistence-unit>中對應的sample定義,Servlet中使用JNDI查找name名稱以取得
EntityManager實例,並透過注入的UserTransaction啟用交易,在交易中進行持久化動作。
若不在類別上使用@PersistenceContext,您也可以在web.xml中加入以下的定義:
....
<persistence-context-ref>
<persistence-context-ref-name>
sample/EntityManager
</persistence-context-ref>
<persistence-unit-name>
sample
</persistence-unit-name>
</persistence-context-ref>
....
第一個方法直接使用@PersistenceUnit注入EntityManagerFactory,例如:
package onlyfun.caterpillar;
import java.io.*;
import java.util.logging.*; import javax.annotation.*; import javax.persistence.*; import javax.servlet.*; import javax.servlet.http.*; import javax.transaction.*;
public class UserAdmin extends HttpServlet { @PersistenceUnit(unitName="sample") private EntityManagerFactory emFactory; @Resource private UserTransaction ut; protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("name"); String age = request.getParameter("age"); User user = new User(); user.setName(name); user.setAge(new Long(Long.parseLong(age))); response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); EntityManager entityManager = null; try { entityManager = emFactory.createEntityManager(); ut.begin(); entityManager.persist(user); ut.commit();
} catch (Exception ex) { Logger.getLogger(UserAdmin.class.getName()) .log(Level.SEVERE, null, ex); } finally { entityManager.close(); out.close(); } }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); }
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } }
類似於 第一個 JPA(單機客戶端) 中的例子,您從注入的EntityManagerFactory中建立EntityManager,之後利用其進行持久化物件或其它的操作。
|