- 译者序
- 前言
- 本书怎么使用
- 本书排版字体约定
- 本书网站
- 致谢
- 第一部分 Hibernate 快速入门
- 第 1 章 安装和设置
- 第 2 章 映射简介
- 第 3 章 驾驭 Hibernate
- 第 4 章 集合与关联
- 第 5 章 更复杂的关联
- 第 6 章 自定义值类型
- 第 7 章 映射标注
- 第 8 章 条件查询
- 第 9 章 浅谈 HQL
- 第二部分 与其他工具的集成
- 第 10 章 将 Hibernate 连接到 MySQL
- 第 11 章 Hibernate 与 Eclipse:Hibernate Tools 使用实战
- 第 12 章 Maven 进阶
- 第 13 章 Spring 入门:Hibernate 与 Spring
- 第 14 章 画龙点睛:用 Stripes 集成 Spring 和 Hibernate
- 附录 A Hibernate 类型
- 附录 B Criteria API
- 附录 C Hibernate SQL 方言
- 附录 D Spring 事务支持
- 附录 E 参考资源
- 作者简介
- 封面介绍
生成 Java 类
我们的映射文件中包含的是有关数据库、Java 类以及它们之间的映射关系的信息。可以用它来帮助我们创建数据库表和 Java 类。首先,我们来看看 Java 类。
应该怎么做
你在第 1 章安装的 Hibernate Tools 中包含一个工具,可以生成匹配映射文档规定的 Java 源代码。只要用一个 Ant 任务就能方便地在 Ant 的构建文件中调用这一工具。编辑 build.xml,把例 2-2 中的黑体部分添加进去。
例 2-2:Ant 构建文件(已经为生成 Java 代码而做了相应的更新)
<?xml version="1.0"?>
<project name="Harnessing Hibernate 3(Developer's Notebook Second Edition)"
default="db"basedir="."
xmlns:artifact="antlib:org.apache.maven.artifact.ant">
<!--Set up properties containing important project directories-->
<property name="source.root"value="src"/>
<property name="class.root"value="classes"/>
<property name="data.dir"value="data"/>
<artifact:dependencies pathId="dependency.class.path">
<dependency groupId="hsqldb"artifactId="hsqldb"version="1.8.0.7"/>
<dependency groupId="org.hibernate"artifactId="hibernate"
version="3.2.5.ga">
<exclusion groupId="javax.transaction"artifactId="jta"/>
</dependency>
<dependency groupId="org.hibernate"artifactId="hibernate-tools"
version="3.2.0.beta9a"/>
<dependency groupId="org.apache.geronimo.specs"
artifactId="geronimo-jta_1.1_spec"version="1.1"/>
<dependency groupId="log4j"artifactId="log4j"version="1.2.14"/>
</artifact:dependencies>
<!--Set up the class path for compilation and execution-->
<path id="project.class.path">
<!--Include our own classes, of course-->
<pathelement location="${class.root}"/>
<!--Add the dependencies classpath-->
<path refid="dependency.class.path"/>
</path>
<!--Teach Ant how to use the Hibernate Tools-->
<taskdef name="hibernatetool"❶
classname="org.hibernate.tool.ant.HibernateToolTask"
classpathref="project.class.path"/>
<target name="db"description="Runs HSQLDB database management UI
against the database file--use when application is not running">
<java classname="org.hsqldb.util.DatabaseManager"
fork="yes">
<classpath refid="project.class.path"/>
<arg value="-driver"/>
<arg value="org.hsqldb.jdbcDriver"/>
<arg value="-url"/>
<arg value="jdbc:hsqldb:${data.dir}/music"/>
<arg value="-user"/>
<arg value="sa"/>
</java>
</target>
<!--Generate the java code for all mapping files in our source tree-->
<target name="codegen"❷
description="Generate Java source from the O/R mapping files">
<hibernatetool destdir="${source.root}">
<configuration>
<fileset dir="${source.root}">
<include name="**/*.hbm.xml"/>
</fileset>
</configuration>
<hbm2java/>
</hibernatetool>
</target>
</project>
我们在构建文件中新添加了一个 taskedf(任务定义)元素,以及一个用于创建文件的 target 元素:
❶这一行的任务定义教给 Ant 一个新技巧:它告诉 Ant 如何使用 Hibernate Tools 中包含的 hibernate tool 任务(有个专门的类为该目的提供帮助)。注意,它也指定了调用这个工具时所需的类路径,并引用 project.calss.path 定义(这个定义包含了 Maven Ant Tasks 为我们管理的所有依赖文件)。当 Ant 需要使用 hibernate 工具时,通过这种办法,就可以找到它们。
❷codegen 构建目标使用 Hibernate Tools(hbm2java)模式来运行 Hibernate 的代码生成器,处理 src 源代码目录中找到的任何映射文件,生成相应的 Java 源代码。"**/*.hbm.xml"这样的匹配模式(pattern)是说“在指定目录或其任何子目录下(无论有多深),任何以.hbm.xml 结尾的文件”。
让我们先试一下吧!从你的项目目录的命令行中,输入以下命令:
ant codegen
你应该看到类似以下内容的输出(假设你运行过前面章节中 ant db 示例,运行那个例子会下载所有必需的依赖文件;如果你还没有运行过那个例子,则此时在下载这些依赖文件时,会多显示许多行信息):
Buildfile:build.xml
codegen:
[hibernatetool]Executing Hibernate Tool with a Standard Configuration
[hibernatetool]1.task:hbm2java(Generates a set of.java files)
[hibernatetool]log4j:WARN No appenders could be found for logger
(org.hibernate.cfg.Environment).
[hibernatetool]log4j:WARN Please initialize the log4j system properly.
BUILD SUCCESSFUL
Total time:2 seconds
以上提示信息大致说的是,我们在第 1 章配置构建文件要安装 log4j,但还没有建立它需要的配置文件,我们将在 2.3 节介绍解决这一问题的办法。现在,如果你去看看 src/com/orielly/hh/data 目录,就会发现出现了一个名为 Track.java 的新文件,其内容如例 2-3 所示。
例 2-3:根据 Track 映射文档生成的 Java 源代码
package com.oreilly.hh.data;
//Generated Sep 2,2007 10:27:53 PM by Hibernate Tools 3.2.0.b9
import java.util.Date;
/**
*Represents a single playable track in the music database.❶
*@author Jim Elliott(with help from Hibernate)
**/
public class Track implements java.io.Serializable{
❷
private int id;
private String title;
private String filePath;
/**
*Playing time
*/
private Date playTime;
/**
*When the track was created
*/
private Date added;
/**
*How loud to play the track
*/
private short volume;
❸
public Track(){
}
public Track(String title, String filePath, short volume){
this.title=title;
this.filePath=filePath;
this.volume=volume;
}
public Track(String title, String filePath, Date playTime, Date added,
short volume){
this.title=title;
this.filePath=filePath;
this.playTime=playTime;
this.added=added;
this.volume=volume;
}
public int getId(){
return this.id;
}
protected void setId(int id){❹
this.id=id;
}
public String getTitle(){
return this.title;
}
public void setTitle(String title){
this.title=title;
}
public String getFilePath(){
return this.filePath;
}
public void setFilePath(String filePath){
this.filePath=filePath;
}
/**
**Playing time
*/
public Date getPlayTime(){
return this.playTime;
}
public void setPlayTime(Date playTime){
this.playTime=playTime;
}
/**
**When the track was created
*/
public Date getAdded(){
return this.added;
}
public void setAdded(Date added){
this.added=added;
}
/**
**How loud to play the track
*/
public short getVolume(){
return this.volume;
}
public void setVolume(short volume){
this.volume=volume;
}
}
这个文件是怎么生成的?Ant 会找出源代码树中所有以.hbm.xml 结尾的文件(目前只有一个),把它们传给 Hibernate 的代码生成器,该代码生成器会分析映射文件,并生成一个满足 Track 映射文件中指定映射要求的 Java 类文件。很明显,这个工具可以为我们节省很多时间,并帮我们完成一些重复性的工作!
注意:Hibernate 可以为我们节省许多时间并完成很多繁琐的操作。要不然,我们一定会被它们搞得晕头转向。
比较生成的 Java 源代码和映射文件中的映射规定(例 2-1),你会有所收获。源代码以相应的包(package)声明作为开始,对于 hbm2java 而言,根据映射文件中指定的完全限定的类名,就可以容易地确定正确的包名:
❶类级的 JavaDoc 看起来应该很眼熟,因为它来自映射文档中 meta 标签的"class-description"。
❷字段声明是来自于映射文档中定义的 id 和 property 标签。源代码中所用到的 Java 类型都是源自于映射文档中的 property 类型声明。学习有关 Hibernate 支持的全部值类型,可以参阅附录 E 提到的资源。目前而言,映射文件内的类型和已生成的代码内的 Java 类型两者间的关系应该相当明确。
❸字段声明之后是三个构造函数的定义。第一个构造函数是创建实例时不用任何参数(如果想让你的类能够作为标准的 bean 来使用,例如在 JSP(Java Server Page)内使用,这是这种数据类非常常见的用法);第二个构造函数只需要提供映射文档中标明不得为 null 的值;最后一个构造函数是为所有属性赋值。注意,这些构造函数都没设置 id 属性的值,当我们从数据库把对象取出或者第一次将对象数据插入数据库时,Hibernate 负责帮我们做这件事。
❹同样,setId()方法的访问类型是 protected,与 id 的映射配置的要求是一样的。后面的 getter 和 setter 方法就没什么特别之处了,都是些照本宣科式的程序代码(我们都写过无数次了),这就是让 Hibernate 工具为我们生成这些代码的妙处所在。
如果你想使用 Hibernate 生成的代码作为起点,并在生成的 Java 类中添加某些业务逻辑或其他功能,一定要记住,你所做出的修改在下一次运行代码生成器时,都会被“悄悄”地丢弃。在这样的项目中,你需要确保手工修改过的类不会被任何 Ant 的构建目标任务重新生成。一种常用的技巧是,把需要手工修改的类扩展成 Hibernate 生成的类。这也是为什么我们要将映射生成的 Java 类隔离到它们自己的代码包和子目录中的原因之一。
虽然此例中 Hibernate 为我们生成了数据类,但需要指出的一个要点是,Hibernate 创建的 getter 和 setter 方法不仅仅是为了样子好看。对于你需要持久化的任何属性,在持久类中都必须具有 getter 和 setter 方法。这是因为 Hibernate 底层的持久化架构是通过反射机制来访问 JavaBeans 风格的属性的。如果你不希望类的属性是公共(public)的,它们可以不必是 public 的(即使属性被声明为 protected 或 private, Hibernate 还是有办法取得这些属性的值),但它们必须具有访问器和修改器方法,即 getter(访问器)和 setter(修改器)方法。这一点也是优秀的面向对象设计应该遵循的准则;Hibernate 团队希望把实际的实例变量(instance variable)的实现细节与底层持久化保存机制完全分离开来。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论