大多数企业项目需要做的第一件事情是建立对象模型。一个对象模型抓取了系统中一组核心的领域对象。一个银行系统可能会有包括Account
,Customer
,Transaction
的对象模型。或者有一个对体育比赛比分建模的系统,有一个Team
和一个Game
对象。不管它是什么,你都需要将你系统中的概念建模成对象模型。在Maven项目中,将这个对象模型分割成单独的项目以被广泛引用,是一种常用的实践。在我们这个系统中,我们将每个对Yahoo!
Weather数据源的查询建模成为Weather
对象,它本身又引用了四个其它的对象。风向,风速等存储Wind
在对象中。地址信息包括邮编,城市等信息存储在Location
类中。大气信息如湿度,可见度,气压等存储在Atmosphere
类中。而对环境,气温,以及观察日期的文本描述存储在Condition
类中。
这个简单对象模型的pom.xml
文件含有一个依赖需要一些解释。我们的对象模型用Hibernate标注符标注了。我们用这些标注来映射模型对象至关系数据库中的表。这个依赖是org.hibernate:hibernate-annotations:3.3.0.ga
。看一下Example 7.2, “simple-model 的 pom.xml”中显示的pom.xml
,然后看接下来几个展示这些标注的例子。
Example 7.2. simple-model 的 pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.sonatype.mavenbook.ch07</groupId> <artifactId>simple-parent</artifactId> <version>1.0</version> </parent> <artifactId>simple-model</artifactId> <packaging>jar</packaging> <name>Simple Object Model</name> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-annotations</artifactId> <version>3.3.0.ga</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-commons-annotations</artifactId> <version>3.3.0.ga</version> </dependency> </dependencies> </project>
在src/main/java/org/sonatype/mavenbook/weather/model
中,有Weather.java
,它是一个标注过的Weather
型对象。这个Weather
对象是一个简单的Java
bean。这意味着它的私有成员变量如id
, location
,
condition
, wind
,
atmosphere
, 和
date
,通过公共的getter和setter方法暴露,并且遵循这样的模式:如果一个属性名为name
,那么会有一个公有的无参数方法getName()
,还有一个带有一个参数的setter方法setName(String
name)
。我们只是展示了id
属性的getter和setter方法,其它属性的getter和setter方法类似,所以这里跳过了,以节省篇幅。请看Example 7.3, “标注的Weather模型对象”。
Example 7.3. 标注的Weather模型对象
package org.sonatype.mavenbook.weather.model; import javax.persistence.*; import java.util.Date; @Entity @NamedQueries({ @NamedQuery(name="Weather.byLocation", query="from Weather w where w.location = :location") }) public class Weather { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer id; @ManyToOne(cascade=CascadeType.ALL) private Location location; @OneToOne(mappedBy="weather",cascade=CascadeType.ALL) private Condition condition; @OneToOne(mappedBy="weather",cascade=CascadeType.ALL) private Wind wind; @OneToOne(mappedBy="weather",cascade=CascadeType.ALL) private Atmosphere atmosphere; private Date date; public Weather() {} public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } // All getter and setter methods omitted... }
在Weather
类中,我们使用Hibernate标注以为simple-persist
项目提供指导。这些标注由Hibernate用来将对象与关系数据库映射。尽管对HIberante标注的完整解释超出了本书的范围,这里是一个为好奇者的简单解释。@Entity
标注标记一个类为持久化对象。我们省略了这个类的@Table
标注,因此Hibernate将会使用这个类的名字来映射表名。@NamedQueries
注解定义了一个simple-persist
中WeatherDAO
使用的查询。@NamedQuery
注解中的查询语句是用一个叫做Hibernate查询语言(HQL)编写的。每个成员变量的注解定义了这一列的类型,以及该列暗示的表关联关系。
Id
-
id
属性用@Id
进行标注。这标记id
属性为一个包含数据库表主键的属性。@GeneratedValue
控制新的主键值如何产生。该例中,我们使用IDENTITY
GenerationType
,它使用了下层数据库的主键生成设施。 Location
-
每个
Weather
对象实例对应了一个Location
对象。一个Location
对象含有一个邮政编码,而@ManyToOne
确认所有指向同一个Location
对象的Weather
对象引用了同样一个实例。@ManyToOne
的cascade
属性确保每次我们持久化一个Weather
对象的时候也会持久化一个Location
对象。 Condition
,Wind
,Atmosphere
-
这些对象的每一个都作为
@OneToOne
而且CascadeType
为ALL
进行映射。这意味着每次我们保存一个Weather
对象,我们将会往Weather
表,Condition
表,Wind
表,和Atmosphere
表,插入一行, Date
-
Date
没有被标注,这以为着Hibernate将会使用所有列的默认值来定义该映射。列名将会是date
,列的类型会是匹配Date
对象的适当时间。Note
如果你有一个希望从表映射中忽略的属性,你可以使用
@Transient
标注这个属性。
接着,看一下一个二级的模型对象,Condition
,如Example 7.4, “simple-model 的 Condition 模型对象”所示。这个类同样也存在于src/main/java/org/sonatype/mavenbook/weather/model
。
Example 7.4. simple-model 的 Condition 模型对象
package org.sonatype.mavenbook.weather.model; import javax.persistence.*; @Entity public class Condition { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer id; private String text; private String code; private String temp; private String date; @OneToOne(cascade=CascadeType.ALL) @JoinColumn(name="weather_id", nullable=false) private Weather weather; public Condition() {} public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } // All getter and setter methods omitted... }
这个Condition
类类似于Weather
类。它被标注为一个@Entity
,在id
属性上也有相似的标注。text
,code
,temp
,和date
属性也都使用默认的列设置,weather
属性使用了@OneToOne
进行标注,而另一个标注通过一个名为weather_id
的外键引用关联的Weather
对象。