您的位置:首页 > 服装鞋帽 > 休闲装 > JPA EntityManager详解(二)

JPA EntityManager详解(二)

luyued 发布于 2011-01-28 22:53   浏览 N 次  
★ 提示 ★

目前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("");
28.
29. out.println("");
30.
31. out.println(" A Servlet");
32.
33. out.println(" ");
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 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(" ");
66.
67. out.println("");
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("");

out.println("");

out.println(" A Servlet");

out.println(" ");

if (emf != null) {

/**创建EntityManager 对象*/

EntityManager entityManager = emf.createEntityManager();

try {

Query query = entityManager

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

List result = query.getResultList();

for (CustomerEO c : result) {

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

}

} finally {

/**关闭EntityManager*/

entityManager.close();

}

}

out.println(" ");

out.println("");

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 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 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 threadLocal;
8.
9.
10.
11. /**初始化*/
12.
13. static {
14.
15. emf = Persistence.createEntityManagerFactory("jpaUnit");
16.
17. threadLocal = new ThreadLocal();
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 threadLocal;

/**初始化*/

static {

emf = Persistence.createEntityManagerFactory("jpaUnit");
threadLocal = new ThreadLocal();

}

/**通过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 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. }
类别:J2ee 查看评论
图文资讯
广告赞助商