JPA EntityManager详解(二)

JPA EntityManager详解(二)
★ 提示 ★
目前JBoss 4.2集成了的Tomcat版本为5.5,但Tomcat 6.0以后的版本中才支持使用注释,所以如果将本例中Servlet运行在JBoss 4.2中,并不能获得EntityManagerFactory对象;但在符合J2EE 5.0的服务器中,这样运行是可以的。

虽然在目前JBoss 4.2版本中不支持使用注释,但可以通过另一种方式来获得应用托管的EntityManager对象。代码如下所示。

1. public class TestServlet extends HttpServlet { 
2.  
3.     private EntityManagerFactory emf; 
4.  
5.     public TestServlet() { 
6.  
7.         super(); 
8.  
9.     } 
10.  
11.     public void doGet(HttpServletRequest request, HttpServletResponse response) 
12.  
13.             throws ServletException, IOException { 
14.  
15.         doPost(request, response); 
16.  
17.     } 
18.  
19.     public void doPost(HttpServletRequest request, HttpServletResponse response) 
20.  
21.             throws ServletException, IOException { 
22.  
23.         response.setContentType("text/html"); 
24.  
25.         PrintWriter out = response.getWriter(); 
26.  
27.         out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional //EN\">"); 
28.  
29.         out.println("<HTML>"); 
30.  
31.         out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>"); 
32.  
33.         out.println("  <BODY>"); 
34.  
35.         if (emf != null) { 
36.  
37.             /**创建EntityManager 对象*/ 
38.  
39.             EntityManager entityManager = emf.createEntityManager(); 
40.  
41.             try { 
42.  
43.                 Query query = entityManager 
44.  
45.                         .createQuery("SELECT c FROM CustomerEO c"); 
46.  
47.                 List<CustomerEO> result = query.getResultList(); 
48.  
49.                 for (CustomerEO c : result) { 
50.  
51.                     System.out.println(c.getId() + "," + c.getName()); 
52.  
53.                 } 
54.  
55.             } finally { 
56.  
57.                 /**关闭EntityManager*/ 
58.  
59.                 entityManager.close(); 
60.  
61.             } 
62.  
63.         } 
64.  
65.         out.println("  </BODY>"); 
66.  
67.         out.println("</HTML>"); 
68.  
69.         out.flush(); 
70.  
71.         out.close(); 
72.  
73.     } 
74.  
75.     /**Servlet初始化时,创建EntityManagerFactory 对象*/ 
76.  
77.     public void init() throws ServletException { 
78.  
79.         if (emf == null) { 
80.  
81.             emf = Persistence.createEntityManagerFactory("jpaUnit"); 
82.  
83.         } 
84.  
85.     } 
86.  
87.     /**Servlet销毁时,关闭EntityManagerFactory对象*/ 
88.  
89.     public void destroy() { 
90.  
91.         if (emf.isOpen()) 
92.  
93.             emf.close(); 
94.  
95.     } 
96.  
97. } 

public class TestServlet extends HttpServlet {

private EntityManagerFactory emf;

public TestServlet() {

super();

}

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doPost(request, response);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional //EN\">");

out.println("<HTML>");

out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");

out.println("  <BODY>");

if (emf != null) {

/**创建EntityManager 对象*/

EntityManager entityManager = emf.createEntityManager();

try {

Query query = entityManager

.createQuery("SELECT c FROM CustomerEO c");

List<CustomerEO> result = query.getResultList();

for (CustomerEO c : result) {

System.out.println(c.getId() + "," + c.getName());

}

} finally {

/**关闭EntityManager*/

entityManager.close();

}

}

out.println("  </BODY>");

out.println("</HTML>");

out.flush();

out.close();

}

/**Servlet初始化时,创建EntityManagerFactory 对象*/

public void init() throws ServletException {

if (emf == null) {

emf = Persistence.createEntityManagerFactory("jpaUnit");

}

}

/**Servlet销毁时,关闭EntityManagerFactory对象*/

public void destroy() {

if (emf.isOpen())

emf.close();

}

}



使用这种方式创建EntityManagerFactory对象需要注意以下几个问题。

可以看到,这里的EntityManagerFactory对象不是通过注入获得的,而是通过Persistence类中的静态方法createEntityManagerFactory来创建的。

— 正因为EntityManagerFactory对象是手动创建的,所以在不再使用时,一定要调用close()方法手动关闭。

11.1.4.3  J2SE环境中获得

在J2SE环境中,获得应用托管的EntityManager对象只能通过手动创建的方式,而不能使用注释的方式,与Web容器中不使用注释的方法相同,都是通过Persistence类中createEntityManagerFactory来创建的。

例如,下面代码为J2SE环境中获得应用托管EntityManager对象的方法。

1. public class CustomerClient { 
2.  
3.     public static void main(String[] args) { 
4.  
5.         /** 创建EntityManagerFactory对象 */ 
6.  
7.         EntityManagerFactory emf = Persistence 
8.  
9.                 .createEntityManagerFactory("jpaUnit"); 
10.  
11.         /** 创建entityManager对象 */ 
12.  
13.         EntityManager entityManager = emf.createEntityManager(); 
14.  
15.         Query query = entityManager.createQuery("SELECT c FROM CustomerEO c"); 
16.  
17.         List<CustomerEO> result = query.getResultList(); 
18.  
19.         for (CustomerEO c : result) { 
20.  
21.             System.out.println(c.getId() + "," + c.getName()); 
22.  
23.         } 
24.  
25.         /** 关闭entityManager对象 */ 
26.  
27.         entityManager.close(); 
28.  
29.         /** 关闭EntityManagerFactory对象 */ 
30.  
31.         emf.close(); 
32.  
33.     } 
34.  
35. } 

public class CustomerClient {

public static void main(String[] args) {

/** 创建EntityManagerFactory对象 */

EntityManagerFactory emf = Persistence

.createEntityManagerFactory("jpaUnit");

/** 创建entityManager对象 */

EntityManager entityManager = emf.createEntityManager();

Query query = entityManager.createQuery("SELECT c FROM CustomerEO c");

List<CustomerEO> result = query.getResultList();

for (CustomerEO c : result) {

System.out.println(c.getId() + "," + c.getName());

}

/** 关闭entityManager对象 */

entityManager.close();

/** 关闭EntityManagerFactory对象 */

emf.close();

}

}


但是,在J2SE环境中使用JPA需要将实现的JPA的第三方类包和数据库的驱动包,设置到当前的运行环境下。

例如,在Eclipse中创建一个Java项目,需要将JPA实现者的类库(这里以Hibernate为例)和MySQL的数据库连接包添加到构建路径中,如图11-2所示。

11.1.5  ThreadLocal的使用

对于在Web容器中使用EntityManager对象,这里需要做一些改进,才能更安全。读者应该了解,Servlet是非线程安全的,所以需要改变获得EntityManager对象的方式,这里笔者建议使用ThreadLocal类。

ThreadLocal就是为每一个使用某变量的线程都提供一个该变量值的副本,使每一个线程都可以独立地改变自己的副本,而不会和其他线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有一个该变量,这就解决了Servlet非线程安全的问题。

首先编写一个EntityManagerHelper类,代码如下所示。

1. public class EntityManagerHelper { 
2.  
3.     
4.  
5.     private static final EntityManagerFactory emf; 
6.  
7.     private static final ThreadLocal<EntityManager> threadLocal; 
8.  
9.     
10.  
11.     /**初始化*/ 
12.  
13.     static { 
14.  
15.         emf = Persistence.createEntityManagerFactory("jpaUnit");        
16.  
17.         threadLocal = new ThreadLocal<EntityManager>(); 
18.  
19.     } 
20.  
21.     
22.  
23.     /**通过threadLocal 获得EntityManager 对象*/ 
24.  
25.     public static EntityManager getEntityManager() { 
26.  
27.         EntityManager manager = threadLocal.get();      
28.  
29.         if (manager == null || !manager.isOpen()) { 
30.  
31.             manager = emf.createEntityManager(); 
32.  
33.             threadLocal.set(manager); 
34.  
35.         } 
36.  
37.         return manager; 
38.  
39.     } 
40.  
41.     
42.  
43.     /**关闭EntityManager 对象*/ 
44.  
45.     public static void closeEntityManager() { 
46.  
47.         EntityManager em = threadLocal.get(); 
48.  
49.         threadLocal.set(null); 
50.  
51.         if (em != null) em.close(); 
52.  
53.     } 
54.  
55.     
56.  
57.     public static void beginTransaction() { 
58.  
59.     getEntityManager().getTransaction().begin(); 
60.  
61.     } 
62.  
63.     
64.  
65.     public static void commit() { 
66.  
67.     getEntityManager().getTransaction().commit(); 
68.  
69.     }  
70.  
71.     
72.  
73.     public static Query createQuery(String query) { 
74.  
75.         return getEntityManager().createQuery(query); 
76.  
77.     } 
78.  
79.     
80.  
81. } 

public class EntityManagerHelper {



private static final EntityManagerFactory emf;

private static final ThreadLocal<EntityManager> threadLocal;



/**初始化*/

static {

emf = Persistence.createEntityManagerFactory("jpaUnit");      

threadLocal = new ThreadLocal<EntityManager>();

}



/**通过threadLocal 获得EntityManager 对象*/

public static EntityManager getEntityManager() {

EntityManager manager = threadLocal.get();    

if (manager == null || !manager.isOpen()) {

manager = emf.createEntityManager();

threadLocal.set(manager);

}

return manager;

}



/**关闭EntityManager 对象*/

public static void closeEntityManager() {

EntityManager em = threadLocal.get();

threadLocal.set(null);

if (em != null) em.close();

}



public static void beginTransaction() {

getEntityManager().getTransaction().begin();

}



public static void commit() {

getEntityManager().getTransaction().commit();

}



public static Query createQuery(String query) {

return getEntityManager().createQuery(query);

}



}



这样经过改进后,在Servlet中创建EntityManager对象的方法修改为如下所示。

1. public class TestServlet extends HttpServlet { 
2.  
3.     public TestServlet() { 
4.  
5.         super(); 
6.  
7.     } 
8.  
9.     public void doPost(HttpServletRequest request, HttpServletResponse response) 
10.  
11.             throws ServletException, IOException { 
12.  
13.             EntityManager entityManager = EntityManagerHelper.getEntityManager(); 
14.  
15.             try { 
16.  
17.                 Query query = entityManager 
18.  
19.                         .createQuery("SELECT c FROM CustomerEO c"); 
20.  
21.                 List<CustomerEO> result = query.getResultList(); 
22.  
23.                 for (CustomerEO c : result) { 
24.  
25.                     System.out.println(c.getId() + "," + c.getName()); 
26.  
27.                 } 
28.  
29.             } finally { 
30.  
31.                 /**关闭EntityManager*/ 
32.  
33.                 EntityManagerHelper.closeEntityManager(); 
34.  
35.             } 
36.  
37.     } 
38.  
39. }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值