Java Passion
Java Persistence API (JPA ) 映射 (四)
(2.2) 显式使用 SINGLE_TABLE 作为继承策略
在本步骤中,我们将通过指定来使用 SINGLE_TABLE 策略。应用程序的行为应该与练习 4.1 相同,因为 SINGLE_TABLE 是默认策略。
1. 根据代码 2.20 修改 Person.java,显式指定 SINGLE_TABLE 策略。需要修改的代码段突出显示为 蓝色的粗体 字。作用是显式指定 SINGLE_TABLE 作为继承策略。
|
package mypackage; import javax.persistence.Inheritance; |
<NetBeans 技巧> 您可能希望使用 NetBeans IDE 对注释的自动完成功能。
- 举例来说,只需键入 @Inh 并按 CTRL+空格 键就可以看到以 @Inh 为首的两个注释:@Inheritance 和 @Inherited。
- 选择 @Inheritance(如图 2.21 所示)
图 2.21:@Inheritance 的代码完成
- 再次按下 CTRL+空格 键。
- 选择 InheritanceType 策略。(如图 2.22 所示)

图 2.22:策略的代码完成
- 按 CTRL+空格 键可以看到两种可能的继承策略。
- 选择 SINGLE_TABLE。(如图 2.23 所示)

图 2.23:SINGLE_TABLE 的代码完成
- @Inheritance(strategy=InheritanceType.SINGLE_TABLE) 已经完成
2. 右键单击刚才创建的行并选择 修复导入。(如果按 CTRL+空格键启用了代码完成功能,则不需要执行此步骤,因为 NetBeans 将自动添加导入。) 3. 查看 SINGLE_TABLE 继承策略的 JavaDoc。
- 右键单击 @Inheritance(strategy=InheritanceType.SINGLE_TABLE) 并选择 显示 Javadoc。(如图 2.25 所示)

图 2.25:显示 Javadoc
- 浏览器将显示 Enum InheritanceType 的 Javadoc。
- 查看 SINGLE_TABLE 和 JOINED 的说明。(如图 2.26 所示)

图 2.26:SINGLE_TABLE 和 JOINED 的 Javadoc
4. 运行应用程序
- 右键单击 ORInheritanceSINGLE_TABLE 项目并选择 运行项目。
- 根据练习 1 中的步骤 9 创建一些 Person 实例和 Student 实例。
6. 右键单击 PERSON 数据库表并选择 删除。(用于后续练习)
返回练习顶部
(2.3) 显式使用 JOINED 继承策略
在本步骤中,我们将使用 JOINED 继承策略。此处的操作与步骤 4.2 相似。为避免混淆,我们将两个类命名为 Person2 和 Student2。
在 JOINED 策略中,特定于子类的字段将映射到一个单独的表中,而不是父类的公共字段,并且将执行合并操作实例化子类。
1. 创建一个 NetBeans 项目。(与上面的步骤 4.2 相同)
- 选择 文件->新建项目(Ctrl+Shift+N)。此时将出现 新建项目 对话框。
- 在 选择项目 窗格中,选择 类别 列表中的 Web,并选择 项目 列表中的 Web 应用程序。单击 下一步 按钮。
- 等待 名称和位置 窗格出现。
- 在 项目名称 字段中,键入 ORInheritanceJOINED。
- 单击 下一步 按钮。
- 等待 框架 窗格出现。
- 选择 JavaServer Faces。
- 单击 完成 按钮。
- 右键单击 ORInheritanceJOINED 项目并选择 新建->持久性单元。
- 等待 提供器和数据库 窗格出现。
- 对于 数据库连接 字段,从下拉菜单中选择 jdbc/sample。
- 对于 表生成策略 字段,选择 删除并创建。每次运行项目时,都将删除已有表并创建新表。
- 单击 完成 按钮。
- 右键单击 ORInheritanceJOINED 项目并选择 新建->实体类。
- 等待 名称和位置 窗格出现。
- 在 类名 字段中,键入 Person2。
- 在 包 字段中,键入 mypackage。
- 单击 完成 按钮。
- 根据上面的代码 2.15 修改 ORInheritanceJOINED->源包->mypackage 中的 Person2.java。
- 在源编辑器中右键单击 name 字段,并选择 重构->封装字段。
- 此时将出现 封装字段 - mypackage.Person 对话框。
- 单击 下一步 按钮。
- 在 输出 区域查看重构的预览效果。
- 单击 执行重构 确认重构操作。
- 现在,Person 类在代码末尾部分拥有了 getName() 和 setName() 方法。
- 右键单击 ORInheritanceJOINED 项目并选择 新建->Java 类。
- 等待 名称和位置 窗格出现。
- 在 类名 字段中,键入 Student2。
- 在 包 字段中,键入 mypackage。
- 单击 完成 按钮。
- 根据代码 2.62 修改 Student2.java。需要修改的代码段突出显示为 蓝色的粗体 字。
| package mypacakge; /** * * @author sang */ @Entity public class Student2 extends Person2 { /** Creates a new instance of Student2 */ public Student2() { } } |
6. 对 Student2.java.执行 修复导入。(如果按 CTRL+空格键启用了代码完成功能,则不需要执行此步骤,因为 NetBeans 将自动添加导入。)
- 注意 @Entity 含有 Cannot find Symbol 编译器错误。
- 右键单击 @Entity 并选择 修复导入。
- 等待 修复导入 对话框出现。
- 从下拉菜单中选择 javax.persitence.Entity。
- 单击 确定 按钮。
- 导入语句已添加,并且编译器错误已经从源编辑器中消失。
7. 将 school 和 grade 字段添加到 Student2.java
- 根据代码 2.63 修改 Student2.java。需要修改的代码段突出显示为 蓝色的粗体 字。
| package mypacakge; import javax.persistence.Entity; /** * * @author sang */ @Entity public class Student2 extends Person2 { String school; double grade; /** Creates a new instance of Student2 */ public Student2() { } } |
- 右键单击 school 字段并选择 重构->封装字段。
- 此时将打开 封装字段 - mypackage.Student2 对话框。
- 选中所有复选框并单击 下一步 按钮。
- 在 输出 区域查看重构的预览效果。
- 单击 执行重构 确认重构操作。
- 现在, getSchool()/setSchool() 和 getGrade()/setGrade() 方法已经添加到代码的末尾部分。
- 根据代码 2.64 修改 Person2.java。需要修改的代码段突出显示为 蓝色的粗体 字。
- 右键单击新创建的行并选择 修复导入。(如果按 CTRL+空格键启用了代码完成功能,则不需要执行此步骤,因为 NetBeans 将自动添加导入。)
| package mypacakge; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; /** * Entity class Person2 * * @author sang */ @Entity @Inheritance(strategy=InheritanceType.JOINED) public class Person2 implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; /** Creates a new instance of Person2 */ public Person2() { } /** * Gets the id of this Person2. * @return the id */ public Long getId() { return this.id; } /** * Sets the id of this Person2 to the specified value. * @param id the new id */ public void setId(Long id) { this.id = id; } /** * Returns a hash code value for the object. This implementation computes * a hash code value based on the id fields in this object. * @return a hash code value for this object. */ @Override public int hashCode() { int hash = 0; hash += (this.id != null ? this.id.hashCode() : 0); return hash; } /** * Determines whether another object is equal to this Person2. The result is * <code>true</code> if and only if the argument is not null and is a Person2 object that * has the same id field values as this object. * @param object the reference object with which to compare * @return <code>true</code> if this object is the same as the argument; * <code>false</code> otherwise. */ @Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof Person2)) { return false; } Person2 other = (Person2)object; if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) return false; return true; } /** * Returns a string representation of the object. This implementation constructs * that representation based on the id fields. * @return a string representation of the object. */ @Override public String toString() { return "mypacakge.Person2[id=" + id + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } } |
9. 通过实体类生成 JavaServer Faces (JSF) 页面
- 右键单击 ORInheritanceJOINED 项目并选择 通过实体类生成 JSF 页面。
- 此时将打开 通过实体类生成 JSF 页面 对话框。
- 单击 添加所有>>,Person2 和 Student2 类将移动到右侧的 选定实体类 部分。
- 单击 下一步 按钮。
- 此时将出现 生成的 JSF 页面和类 窗格。
- 接受所有默认设置并点击 完成 按钮。
- 右键单击 ORInheritanceJOINED 项目并选择 运行项目。
- 此时将打开浏览器。
- 添加一些 Person2 实例和 Student2 实例。
在本步骤中,我们将验证所创建的数据库表。在 JOINED 策略中,应该存在两个表,PERSON 表用于保存层次结构中的常用数据字段,STUDENT 表用于保存特定于 Student 实体的字段。
- 展开 jdbc:derby://localhost:1527/sample [APP 上的 app]。
- 展开 表。(如果 表 已经展开,则右键单击它并选择 刷新)
- 现在,PERSON2 和 STUDENT2 表已经创建。
- 右键单击 PERSON2 表并选择 查看数据。注意,它只有一个 NAME 列。(如图 2.65 所示)

图 2.65:PERSON2 表
- 右键单击 STUDENT2 表并选择 查看数据。
- 它含有 SCHOOL 和 GRADE 列。(如图 2.66 所示)

解决方案
针对此练习的解决方案作为可运行的 NetBeans 项目包含在动手实验室的压缩文件中。
- ORInheritanceSINGLE_TABLE 项目位于 <LAB_UNZIPPED_DIRECTORY>/jpamapping/solutions/ORInheritanceSINGLE_TABLE。
- ORInheritanceJOINED 项目位于 <LAB_UNZIPPED_DIRECTORY>/jpamapping/solutions/ORInheritanceJOINED。
结束语
返回顶部
课外练习(针对 Sang Shin“Java EE 编程在线课程”的学习者)
- 在 Person2 实体类中再添加一个名称为 Teacher2 的子类。
- 将以下两个字段添加到 Teacher2 类中。
- String subjectToTeach // Subject he or she teaches
- int years // Number of years he or she have taught
- String subjectToTeach // Subject he or she teaches
2. 将 J2EEHomework-jpamapping 项目中的文件发送到 j2eehomeworks@sun.com。
- MyORInheritanceJOINED NetBeans 项目的压缩文件。。(其他人应该能够打开它,并能将它作为 NetBeans 项目运行。)您可以使用任意压缩工具,也可以使用 JDK 提供的 jar 实用工具,使用方法如下所示:
- cd <parent directory that contains MyORInheritanceJOINED directory> (假设您将项目命名为 MyORInheritanceJOINED)
- jar cvf MyORInheritanceJOINED.zip MyORInheritanceJOINED (MyORInheritanceJOINED 应该包含 nbproject 目录)
- cd <parent directory that contains MyORInheritanceJOINED directory> (假设您将项目命名为 MyORInheritanceJOINED)
- 抓取输出屏幕 - 将它命名为 J2EEHomework-jpamapping.gif 或 J2EEHomework-jpamapping.jpg (或 J2EEHomework-jpamapping。<任意图像格式都可>)
- 抓取的屏幕截图只需显示程序正常运行即可。
- 抓取的屏幕截图只需显示程序正常运行即可。
- 如果决定使用 NetBeans 之外的其他 IDE,则压缩文件应该包含重新编译项目所需的所有文件(含有所需源文件的 War 文件也可以)。
Posted at 12:52AM Apr 01, 2008 by Sang Shin in Java EE | Comments[0]