[转载]使用 Apache OpenJPA 开发 EJB 3.0 应用,第 2 部分: 开发第一个 Open JPA 应用

使用 Apache OpenJPA 开发 EJB 3.0 应用,第 2 部分: 开发第一个 Open JPA 应用


2007 年 6 月 25 日

JPA 是 EJB 3.0 新引入的数据持久化编程模型。JPA 充分利用了注释(Annotation)和对象/关系映射,为数据持久化提供了更简单、易用的编程方式。OpenJPA 是 Apache 组织提供的 JPA 标准实现。本文是 使用 Apache OpenJPA 开发 EJB 3.0 应用系列 的第二部分,描述了如何采用 OpenJPA 提供的接口开发 EJB 3.0 应用的步骤和方法,并介绍了 OpenJPA 中提供的几个小工具的用法,这些工具能让我们的开发过程变得更加简单、快速。

上一部分中, 我们了解了 EJB 3.0 标准和 OpenJPA 的基本特性,现在我们将开始讲述如何使用 OpenJPA 开发企业应用。本文中,我们将假设有一个 Animal 对象,在某一个应用场景中,我们需要使用 OpenJPA 框架提供的工具和接口完成 Animal 对象的持久化、属性修改、删除、查找功能。本文将通过简单的文字和代码描述使用 OpenJPA 开发的步骤和方法,以及开发过程中如何使用 OpenJPA 提供的工具协助完成开发任务。

下载及安装 OpenJPA

支持环境准备

由于 OpenJPA 是基于注释机制的框架,这需要用到 JDK 5.0 或者以上版本,因此请确保在工作机器上已经下载和安装了 JDK 5.0(参见 参考资源)。

演示过程中,我们需要一个数据库作为对象持久化的目标数据库。出于简单和方便的考虑,我们选择采用 MySQL 数据库,因此您需要下载 MySQL 数据库安装包(请见 参考资源)。如果需要 MySQL 很好的支持中文字符(GB2312 编码),您可选择下载 MySQL 5.0 或者以上版本,安装的时候选择数据库字符集为 GB2312 即可。

下载、安装 OpenJPA

OpenJPA 的最新稳定版本是 Open JPA 0.97(下载链接见 参考资源)。OpenJPA 的安装比较简单,只需要将下载的压缩文件解压即可。我们假设将下载的压缩包解压到 C:/OpenJPA 目录下(本文后面将使用 %OPENJPA_HOME% 来引用这个目录)。

使用 OpenJPA 开发 EJB 3.0 应用

成 功安装 OpenJPA 后,我们就可以开始应用 OpenJPA 框架开发 EJB 3.0 应用了。下面的章节中我们将讲述应用 OpenJPA 框架开发 EJB 3.0 应用的主要步骤。为了把描述集中在 OpenJPA 本身而不涉及太多的其它内容,在本演示场景中,我们在轻量级应用中来使用 OpenJPA,开发出的应用基于 Java SE 环境运行,而不依赖于 EJB 容器,关于如何在 Java EE 中配置使用 OpenJPA 将是另外一个主题,本文将暂不涉及,本系列的后续文章中将会讨论这个主题。

通常情况下,使用 OpenJPA 框架开发持久层主要有以下步骤:

  1. 编写(或修改)OpenJPA 配置文件;

    在 非 JavaEE 环境下,OpenJPA 通常使用 CLASSPATH 环境下的 META-INFpersistence.xml 文件来创建 EntityManagerFactory,而每一个被管理的 Java 实体类必须在 persistence.xml 中注册后才能被 EneityManager 处理。

  2. 根据业务需要设计 Java 对象、编写对应的 Java 实体类;
  3. 用 JDK 编译 Java 实体类;
  4. 用 OpenJPA 提供的工具 — PCEnhancer 来增强(enhance)编译好的 Java 实体类;被增强过的类可以提供更好的运行性能、灵活的 "懒加载" 等方面的优势,更多详细的内容请参考 OpenJPA 的帮助文档。
  5. 使用 OpenJPA 提供的工具 MappingTool 从 Java 对象生成数据库定义文件(DDL);

    可以通过 MappingTool 工具直接保持 Entity 和数据库之间的一致性,也可以使用 MappingTool 工具生成的数据库定义文件(DDL)创建应用正常运行所需要的数据库结构。

  6. 将创建的实体类注册到 OpenJPA 容器中;
  7. 应用 JPA 接口编写实体类访问代码,实现相应的业务逻辑。

下 面我们将用一个简单的例子来说明创建 OpenJPA 应用的典型步骤,实例中我们将创建名为 Animal 的持久化对象,它有两个属性,分别是 “id”和 “name”,Animal 对象将被持久化到本地的 MySQL 数据库中,其中 id 属性对应的数据库字段由 MySQL 数据库自动生成。

开发环境说明

本 文的演示说明均基于 Windows XP 平台,JDK 版本为 1.5.0_11,数据库服务器为 MySQL 5.0,和演示代码位于同一台机器上。所有演示用例对应的 MySQL 数据库为“openjpa”,访问 MySQL 的用户名和密码也均为“openjpa”。

OpenJPA 应用开发典型步骤

请读者注意,后面章节中关于操作的说明均基于 Windows XP 操作系统,如果您使用的开发环境运行在其它类型的操作系统之上,请根据实际情况做出相应的调整。

建立工程目录

在 C: 盘根目下创建名为 OpenJPAExamples 的目录,我们所有的类文件和配置文件都将放在这个目录下。

编写 JPA 配置文件

在 C:OpenJPAExamples 新建 META-INF 目录,随后在该目录下创建 persistence.xml 文件。persistence.xml 是 OpenJPA 的配置文件,提供 OpenJPA 容器初始化、运行所需要的配置信息。比如 OpenJPA 的事务策略、数据库的连接信息等。清单 1 中是我们演示实例中所使用的 persistence.xml 文件的内容。


清单 1 META-INFpersistence.xml
1.	<?xml version="1.0" encoding="UTF-8"?>
2. 3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4. version="1.0">
5. 6. 关键字,transaction-type则指定了使用的事务管理类型,这里使
7. 用‘RESOURCE_LOCAL’参数表示使用本地事务 
8.
9. 10. 的内容需要修改成相应的提供类 
11.
12. org.apache.openjpa.persistence.PersistenceProviderImpl
13.
14.
15. 16. org.vivianj.openjpa.entity.Animal
17. 18.
19. 20. value="jdbc:mysql://localhost/openjpa"/>
21. 22. value="com.mysql.jdbc.Driver"/>
23. 24. value="openjpa"/>
25. 26. value="openjpa"/>
27.
28.
29.

创建实体类

新 创建实体类 Animal,为了说明的简单,该类只有两个属性:id 和 name,其中 id 字段代表的是编号(编号由 MySQL 数据库自动生成),name 属性表示名称。实体类的全部代码见清单 2,请注意其中的黑体部分,它们是 JPA 中定义的注释(Annotation),Animal 中仅仅用到了非常少的几个注释,了解其它更多注释的细节请参看 OpenJPA 的帮助文档。


清单 2 Animal.java
1.	package org.vivianj.openjpa.entity;
2.
3. import javax.persistence.Basic;
4. import javax.persistence.Entity;
5. import javax.persistence.GeneratedValue;
6. import javax.persistence.GenerationType;
7. import javax.persistence.Id;
8.
9. /*
10. * 使用Entity注释表示该类是实体类,它的name属性是该实体在查询中对应的
11. * 唯一名称,如果没有提供Entity的name属性,默认的name属性是类名。
12. */
13. @Entity
14. public class Animal {
15. // 编号
16. /* 使用Id注释表示该字段是标识字段 */
17. @Id
18. /*
19. * 使用GeneratedValue注释定义该标识字段的产生方式,我们的演示系统中
20. * id由MySQL数据库字段自动生成,因此选择GenerationType.IDENTITY,
21. * 另外的可选方式包括GeneratorType.AUTO,GenerationType.SEQUENCE,
22. * GenerationType.TABLE。
23. */
24. @GeneratedValue(strategy = GenerationType.IDENTITY)
25. private int id;
26.
27. // 名称
28. /*
29. * Basic注释表示该属性是持久化属性,没有使用Basic注释的属性将不会
30. * 被持久化到数据库中
31. */
32. @Basic
33. private String name;
34.
35. public int getId() {
36. return id;
37. }
38.
39. public void setId(int id) {
40. this.id = id;
41. }
42.
43. public String getName() {
44. return name;
45. }
46.
47. public void setName(String name) {
48. this.name = name;
49. }
50.
51. }

编译实体类

打开命令行控制台,进入 C:OpenJPAExamples 目录,执行下面的系列语句可以编译实体类 Animal.java。

C:OpenJPAExamples>set OPENJPA_HOME=C:OpenJPA
C:OpenJPAExamples>set classpath=%OPENJPA_HOME%libpersistence-api-1.0.jar
C:OpenJPAExamples>javac Animal.java -d

[注] 上面的命令行中第一行出现的 C:OpenJPA 是指 OpenJPA 框架的安装目录。如果您没有使用 C:/OpenJPA 作为 OpenJPA 的安装目录,请将 OPENNJPA_HOME 的值修改为您安装 OpenJPA 的目录。

增强(Enhance)实体类

Enhance 是使用 OpenJPA 必须的一个步骤,所谓 Enhance 是指使用 OpenJPA 提供的工具 PCEnhancer(org.apache.openjpa.enhance.PCEnhancer)对实体类进行处理的过程,被 Enhance 过的实体类能够支持性能优化、懒惰式装载等高级特性。

OpenJPA 支持在编译时、部署时、运行时增强实体类,我们以编译时为例了解如何增强实体类。我们使用下面的系列语句完成实体类的增强(Enhance)。

1.	C:OpenJPAExamples>set OPENJPA_HOME=C:OpenJPA
2. C:OpenJPAExamples>set classpath= %OPENJPA_HOME%libcommons-collections-3.2.jar;
%OPENJPA_HOME%libcommons-lang-2.1.jar;
%OPENJPA_HOME%libcommons-logging-1.0.4.jar;
%OPENJPA_HOME%libcommons-pool-1.3.jar;
%OPENJPA_HOME%libgeronimo-j2ee-connector_1.5_spec-1.0.1.jar;
%OPENJPA_HOME%libgeronimo-jms_1.1_spec-1.0.1.jar;
%OPENJPA_HOME%libgeronimo-jta_1.0.1B_spec-1.0.1.jar;
%OPENJPA_HOME%libpersistence-api-1.0.jar;
%OPENJPA_HOME%libserp-1.11.0.jar;
%OPENJPA_HOME%openjpa-all-0.9.6-incubating.jar
3. C:OpenJPAExamples>java org.apache.openjpa.enhance.PCEnhancer Animal.java

有兴趣的读者可以使用反射 (Reflect)机制获取经过 Enhance 的类的信息,清单 3 中给出了被 Enhance 过后 Animal 实体类的类声明和方法签名信息,从中我们可以看到 Animal 被增加了新的 org.apache.openjpa.enhance.PersistenceCapable 接口,而该接口声明的方法都是和实体创建、状态保持等相关的。事实上,OpenJPA 通过 Enhance 过程修改我们的实体类,扩充了实体类的能力,从而实现性能优化、懒惰式装载等高级特性。


清单 3 Animal 被 Enhance 过后的类声明和方法信息
1.	public class org.vivianj.openjpa.entity.Animal 
2. extends java.lang.Object
3. implements org.apache.openjpa.enhance.PersistenceCapable{
4. protected transient org.apache.openjpa.enhance.StateManager pcStateManager;
5. protected transient byte pcFlags;
6. static java.lang.Class class$Ljava$lang$String;
7. static java.lang.Class class$Lorg$vivianj$openjpa$entity$Animal;
8. public org.vivianj.openjpa.entity.Animal();
9. public int getId();
10. public void setId(int);
11. public java.lang.String getName();
12. public void setName(java.lang.String);
13. static final {};
14. static java.lang.Class class$(java.lang.String);
15. protected void pcClearFields();
16. public org.apache.openjpa.enhance.PersistenceCapable pcNewInstance(
17. org.apache.openjpa.enhance.StateManager, java.lang.Object, boolean);
18. public org.apache.openjpa.enhance.PersistenceCapable pcNewInstance(
19. org.apache.openjpa.enhance.StateManager, boolean);
20. protected static int pcGetManagedFieldCount();
21. public void pcReplaceField(int);
22. public void pcReplaceFields(int[]);
23. public void pcProvideField(int);
24. public void pcProvideFields(int[]);
25. protected void pcCopyField(org.vivianj.openjpa.entity.Animal, int);
26. public void pcCopyFields(java.lang.Object, int[]);
27. public java.lang.Object pcGetGenericContext();
28. public java.lang.Object pcFetchObjectId();
29. public boolean pcIsDeleted();
30. public boolean pcIsDirty();
31. public boolean pcIsNew();
32. public boolean pcIsPersistent();
33. public boolean pcIsTransactional();
34. public boolean pcSerializing();
35. public void pcDirty(java.lang.String);
36. public org.apache.openjpa.enhance.StateManager pcGetStateManager();
37. public java.lang.Object pcGetVersion();
38. public void pcReplaceFlags();
39. public synchronized void pcReplaceStateManager(
40. org.apache.openjpa.enhance.StateManager)
41. throws java.lang.SecurityException;
42. public void pcCopyKeyFieldsToObjectId(
43. org.apache.openjpa.enhance.FieldSupplier, java.lang.Object);
44. public void pcCopyKeyFieldsToObjectId(java.lang.Object);
45. public void pcCopyKeyFieldsFromObjectId(
46. org.apache.openjpa.enhance.FieldConsumer, java.lang.Object);
47. public void pcCopyKeyFieldsFromObjectId(java.lang.Object);
48. public java.lang.Object pcNewObjectIdInstance(java.lang.Object);
49. public java.lang.Object pcNewObjectIdInstance();
50. public java.lang.Boolean pcIsDetached();
51. public java.lang.Object pcGetDetachedState();
52. public void pcSetDetachedState(java.lang.Object);
53. }

将新创建的实体类注册到 OpenJPA 容器中

在 OpenJPA 框架中,如果创建了新的实体类,必须通过修改配置文件,将它注册到 OpenJPA 容器中,该实体类才能够被 OpenJPA 管理。将实体类方法注册到 OpenJPA 容器中的方法是在 persistence.xml 中对应的 persistence-unit 元素下增加子元素 class,元素的内容就是被注册持久类的全名。比如我们要把 org.vivianj.openjpa.entity.Animal 注册到 OpenJPA 容器中,我们可以在 persistence.xml 中加入如下内容:

1.	
2.
3. …
4. org.vivianj.openjpa.entity.Animal
5. …
6.
7.

准备数据库

在 MySQL 数据库中新建名为“openjpa”的数据库。新创建数据库的访问用户为“openjpa”,密码设置为“openjpa”,新创建的用户“openjpa”必须具有访问读写“openjpa”数据库数据的权限。

保持实体类和数据库表结构一致性

OpenJPA 中提供了专门的 MappingTool(org.apache.openjpa.jdbc.meta.MappingTool)工具协助开发者保持实体类和数据库表结构 之间的一致性。MappingTool 工具能够自动的根据实体类中提供的注释(Annotation),识别出对象、对象之间的继承/包含等关系以及如何在关系型数据库中处理这些关系的设置, 自动保证实体类和数据库之间的一致性,开发者也可以选择使用 OpenJPA 生成创建数据库所需要的 SQL 语句,然后手动的保持实体类和数据库之间的一致性。

可以使用下面的命令语句直接通过 MappingTool 在数据库中创建 OpenJPA 应用所需要的数据库表。

java org.apache.openjpa.jdbc.meta.MappingTool Animal.java

命令执行完成后,我们通过 MySQL 的客户端访问 OpenJPA 数据库,可以发现里面已经创建了名为“animal”的数据表。如果开发者不想让 MappingTool 自动维护 OpenJPA 和数据库之间的映射,而只是想让 MappingTool 协助生成创建数据库所需要的数据库表定义文件(DDL),可以使用下面的命令语句,其中的参数 -sql 的值就是生成数据库表定义文件的位置。

比如要将生成的数据库表定义文件写入当前文件夹下 animal.sql 文件的命令如下:

java org.apache.openjpa.jdbc.meta.MappingTool –sql animal.sql Animal.java

[注] 要成功执行 MapptingTool 工具,必须先将数据库的 JDBC 驱动放入到 classpath 中,否则会得到一个 org.apache.openjpa.util.StoreException 类型的异常信息。

访问持久化对象

访问 OpenJPA 容器中管理的持久化对象所需要的基本步骤如下:

  1. 获取 OpenJPA 容器中配置好的 EntityManagerFactory 对象;
  2. 从 EntityManagerFactory 中获取 EntityManager 对象;
  3. 如果是处理持久化对象的创建、更新、删除动作,还需要从 EntityManager 中获取 EntityTransaction,并且调用其 begin(commit)方法显式的启动(提交)事务;
  4. 操作持久化对象
    1. 调用 EntityManager 的 persist 方法可以持久化对象到数据库中;
    2. 调用 EntityManager 的 merge 方法可以更新对象状态;
    3. 调用 EntityManager 的 remove 方法可以删除持久化对象,另外一种选择是通过 Query 接口删除对象。
  5. 查询持久化对象
    1. 根据对象的主键查找符合条件的对象,可以直接使用 EntityManager 的 find 方法;
    2. 要查询 EntityManager 中符合条件的对象列表,还需要借助 Query 接口和 JPQL(Java Persistence Query Language)查询语言。

下面的章节中我们将逐一了解如何通过 OpenJPA 中的相关接口完成这些步骤。

获取 OpenJPA 容器中的 EntityManagerFactory

EntityManagerFactory 是 OpenJPA 中创建 EntityManager 的工厂,要想得到 EntityManager,就必须获取的相应的 EntityManagerFactory。

EntityManagerFactory 通过 Persistence 的静态方法 createEntityManagerFactory 获得,该方法是一个重载的方法,支持不同的输入参数。最常用的是使用一个字符串作为参数,该字符串的内容是 EntityManagerFactory 的标识名,该标识名需要和 persistence.xml 文件中的 persistence-unit 元素的 name 属性保持一致。可以使用 null 作为 createEntityManagerFactory 方法的参数,这时候将使用 persistence.xml 中没有提供 name 属性的 persistence-unit 元素提供的参数来配置 EntityManagerFactory。

下面的代码段可以从 OpenJPA 容器中获取名为“mysql”的 EntityManagerFactory。

EntityManagerFactory factory = Persistence.createEntityManagerFactory("mysql");

而它对应的 persistence.xml 文件中,应该有相应的 name 属性为“mysql”的 persistence-unit 元素,下面的配置是一个示例。

1.	2.	    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3. version="1.0">
4.
5. …
6.
7.

为了提升软件的执行效率,我们通常选 择在某一个范围内缓存 EntityManagerFactory 对象。在 EntityManagerFactory 使用完后,我们需要调用它的 close 方法来释放相应的资源。获取、使用 EntityManagerFactory 的实际例子请参考 清单 4 AnimalDAOImpl.java 中的源代码。

获取 EntityManager

要 访问 OpenJPA 容器中的实体类,必须首先获得相应的 EntityManager。可以通过 EntityManagerFactory 对象的 createEntityManager() 方法来获取 EntityManager 对象。获取、使用 EntityManager 的实际例子请参考 清单 4 AnimalDAOImpl.java 中的源代码。

EntityTransaction的启动(提交)

对 于 OpenJPA 容器中的持久化对象的创建、修改、删除操作必须在代码中显式的处理事务,而对于查询操作则不需要在代码中显式的处理事务。JPA 应用中的事务由 EntityTransaction 接口处理,EntityTransaction 可以直接通过 EntityManager 对象的 getTransaction 方法获得。我们可以调用 EntityTransaction 的 begin(commit) 方法显式的启动(提交)事务。获取、使用 EntityTransaction 的实际例子请参考 清单 4 AnimalDAOImpl.java 中的源代码。

Query 接口和 JPQL 查询语言

要 查询 EntityManager 中符合条件的对象列表,需要借助 Query 接口和 JPQL。Query 接口可以直接通过 EntityManager 的 createQuery 方法获得。Query 对象目前支持 JPQL 和原生态 SQL 两种方式。

JPQL 是 OpenJPA 中支持的对象查询语言,是 EJB SQL 的一种实现。通过 JPQL,我们可以用一种面向对象的方式编写持久化对象的查询条件。比如要查找编号为“1”的 Animal 对象,我们可以使用下面的 JPQL 语法:

select animal form Animal animal where animal.id=1)

关于 JPQL 的更多信息请参考 OpenJPA 的帮助文档。Query 接口和 JPQL 的实际例子请参考 清单 4 AnimalDAOImpl.java 中的源代码。

清单 4 中列出了如何使用 OpenJPA 操作、查找持久化对象 Animal 的源代码,读者可以从中了解使用 OpenJPA 时所应该完成的步骤和方法。


清单 4 AnimalDAOImpl.java
1.	package org.vivianj.openjpa.impl.ejb3;
2.
3. import java.util.List;
4.
5. import javax.persistence.EntityManager;
6. import javax.persistence.EntityManagerFactory;
7. import javax.persistence.Persistence;
8. import javax.persistence.Query;
9.
10. import org.vivianj.openjpa.dao.AnimalDAO;
11. import org.vivianj.openjpa.entity.Animal;
12.
13. /**
14. * AnimalDAOImpl 演示了如何使用OpenJPA访问数据库的方法和步骤
15. *
16. */
17. public class AnimalDAOImpl implements AnimalDAO {
18.
19. /**
20. * removeAnimal方法可以从数据库中删除指定编号的Animal对象
21. *
22. * @param id
23. * Animal对象的编号
24. */
25. public void removeAnimal(int id) {
26. // 获取EntityManagerFactory
27. EntityManagerFactory factory = Persistence
28. .createEntityManagerFactory("mysql");
29. // 获取EntityManager
30. EntityManager em = factory.createEntityManager();
31. // 开始事务处理
32. em.getTransaction().begin();
33.
34. // 使用Query删除对象
35. em.createQuery("delete from Animal animal where animal.id=" + id)
36. .executeUpdate();
37.
38. // 我们还可以选择通过Query对象来完成
39. /*
40. * // 从EntityManager中查询到符合条件的对象 Animal animal =
41. * em.find(Animal.class,id); // 调用EntityManager的remove方法删除对象
42. * em.remove(animal);
43. */
44.
45. // 提交事务
46. em.getTransaction().commit();
47. // 关闭EntityManager
48. em.close();
49. // 关闭EntityManagerFactory
50. factory.close();
51.
52. }
53.
54. /**
55. * findAnimalsByName 通过输入的name内容模糊查找符合条件的Animal对象列表
56. *
57. * @param name
58. * Animal对象的name
59. * @return 符合模糊查找条件的Animal对象列表
60. */
61. public List findAnimalsByName(String name) {
62. // 获取EntityManagerFactory
63. EntityManagerFactory factory = Persistence
64. .createEntityManagerFactory("mysql");
65. // 获取EntityManager
66. EntityManager em = factory.createEntityManager();
67.
68. /*
69. * 通过EntityManager的createQuery方法获取Query对象
70. * createQuery方法的参数是JPQL查询语句,JPQL语句的语法请参考OpenJPA的帮助文档.
71. *
72. * 由于查询不需要事务的支持,因此Query操作的前后没有出现begin、commit方法的调用
73. *
74. */
75. Query q = em
76. .createQuery("select animal from Animal animal where animal.name like '%"
77. + name + "%' ESCAPE ''");
78. List l = q.getResultList();
79. // 关闭EntityManager
80. em.close();
81. // 关闭EntityManagerFactory
82. factory.close();
83.
84. return l;
85. }
86.
87. /**
88. * getAnimalByPrimaryKey 方法可以查找符合条件的单个Animal对象,
* 如果不存在对应的Animal对象将返回null
89. *
90. * @param id
91. * Animal对象的编号
92. * @return 唯一符合条件的Animal对象
93. *
94. */
95. public Animal getAnimalByPrimaryKey(int id) {
96. // 获取EntityManagerFactory
97. EntityManagerFactory factory = Persistence
98. .createEntityManagerFactory("mysql");
99. // 获取EntityManager
100. EntityManager em = factory.createEntityManager();
101.
102. // 查找符合条件的对象
103. Animal animal = em.find(Animal.class, id);
104.
105. // 关闭EntityManager
106. em.close();
107. // 关闭EntityManagerFactory
108. factory.close();
109.
110. return animal;
111. }
112.
113. /**
114. * 将对象持久化到数据库中
115. *
116. * @param animal
117. * 需要被持久化的对象
118. */
119. public void persistAnimal(Animal animal) {
120. // 获取EntityManagerFactory
121. EntityManagerFactory factory = Persistence
122. .createEntityManagerFactory("mysql");
123. // 获取EntityManager
124. EntityManager em = factory.createEntityManager();
125. // 开始事务处理
126. em.getTransaction().begin();
127.
128. // 持久化对象
129. em.persist(animal);
130.
131. // 提交事务
132. em.getTransaction().commit();
133. // 关闭EntityManager
134. em.close();
135. // 关闭EntityManagerFactory
136. factory.close();
137. }
138.
139. /**
140. * 将Animal对象被更新的属性持久化到数据库中
141. *
142. * @param animal
143. * 被更新过的Animal对象
144. */
145. public void updateAnimal(Animal animal) {
146. // 获取EntityManagerFactory
147. EntityManagerFactory factory = Persistence
148. .createEntityManagerFactory("mysql");
149. // 获取EntityManager
150. EntityManager em = factory.createEntityManager();
151. // 开始事务处理
152. em.getTransaction().begin();
153.
154. // 更新持久化对象状态
155. em.merge(animal);
156.
157. // 提交事务
158. em.getTransaction().commit();
159. // 关闭EntityManager
160. em.close();
161. // 关闭EntityManagerFactory
162. factory.close();
163.
164. }
165.
166. }

总结

本 文中首先描述了如何准备 OpenJPA 开发环境所需要的支持环境,接着说明了 OpenJPA 下载、安装的步骤。随后,通过一个简单的例子,作者讲解了如何应用 OpenJPA 开发 EJB 3.0 应用的步骤和方法,并且通过合适的代码演示了如何使用 JPA 标准接口访问持久化对象。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/374079/viewspace-130056/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/374079/viewspace-130056/

PaddlePaddle是一个开源的深度学习平台,可以用于构建和训练深度学习模型。如果你想使用PaddlePaddle,可以通过源码编译的方式来安装。首先,你需要在Git Bash中执行以下两条命令来将PaddlePaddle的源码克隆到本地,并进入Paddle目录: ``` git clone https://github.com/PaddlePaddle/Paddle.git cd Paddle ``` 接下来,你可以根据自己的需求进行编译。如果你使用的是Windows系统,可以使用源码编译来安装符合你需求的PaddlePaddle版本。具体的编译步骤可以参考官方文档中的Windows下源码编译部分\[2\]。 如果你想在docker镜像中编译PaddlePaddle,可以使用以下命令启动docker镜像并进行编译。如果你需要编译CPU版本,可以使用以下命令: ``` sudo docker run --name paddle-test -v $PWD:/paddle --network=host -it hub.baidubce.com/paddlepaddle/paddle:latest-dev /bin/bash ``` 如果你需要编译GPU版本,可以使用以下命令: ``` sudo nvidia-docker run --name paddle-test -v $PWD:/paddle --network=host -it hub.baidubce.com/paddlepaddle/paddle:latest-dev /bin/bash ``` 以上是关于使用源码编译PaddlePaddle的一些基本步骤和命令。你可以根据自己的需求和操作系统选择适合的方式来安装PaddlePaddle。 #### 引用[.reference_title] - *1* *2* *3* [《PaddlePaddle从入门到炼丹》一——新版本PaddlePaddle的安装](https://blog.csdn.net/qq_33200967/article/details/83052060)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值