這些年來,Hibernate幾乎已經(jīng)成為java世界中數(shù)據(jù)庫持久化方面事實上的標準,它強大靈活并且性能優(yōu)秀.在這篇文章中,我們來看一下Java 5的注解功能怎么簡單地用在你的hibernate代碼中讓你的持久化層變得更容易.
在過去,Hibernate 依靠外部的XML文件來配置持久化對象,數(shù)據(jù)庫映射文件定義在一組XML映射文件里并且在程序開始的時候被裝載.有很多辦法來創(chuàng)建這些映射文件,或者自動從一個已存在的數(shù)據(jù)庫模式里創(chuàng)建,或者手動從java類對象中創(chuàng)建.不管那種情況,你都得產(chǎn)生一大堆Hibernate 映射文件而結束工作.,你也可以利用外部工具從javadoc-style 的注解中生成映射文件,但這給你的開發(fā)流程增加了額外的負擔.
在最近的Hibernate版本里,一個新的建立在Java 5 注解之上更為優(yōu)雅的方法出現(xiàn)了.利用新的Hibernate Annonations 庫,你可以發(fā)布一次如你以前的映射文件所定義的信息,你猜到了-注解直接嵌入你的Java類文件里.注解帶來了一種強大靈活地聲明持久化映射的辦法.在最新版的幾個Java集成開發(fā)環(huán)境里都很好的支持,并帶有代碼自動完成和語法高亮功能.
Hibernate annotations 也支持最新的EJB 3持久化規(guī)范,這些規(guī)范目的是提供一個標準的Java持久化機制.當然Hibernate 3也提供了更多的解決方案,你能非常容易的靠近保準并且利用EJB 3編程模型編寫你的Hibernate持久化層.
現(xiàn)在讓我們一步步了解Hibernate Annotations.
版權聲明:任何獲得Matrix授權的網(wǎng)站,轉載時請務必保留以下作者信息和鏈接作者:
kjj原文:
http://www.matrix.org.cn/resource/article/2007-04-09/Hibernate+Annotations_62c034f4-e62a-11db-b1bd-fb5572962927.html關鍵字:Hibernate Annotations
安裝 Hibernate Annotations為了使用Hibernate Annotations,你需要最新的Hibernate 3.2 ,當然還有Java 5 你可以在Hibernate web site 這個網(wǎng)站下載Hibernate 3.2和Hibernate Annotations庫.除了標準的Hibernate 庫文件和必須的依賴庫之外,還需要下載 Hibernate Annotations庫和Java 持久化API ---ejb3-persstence.jar文件.如果你正在使用Maven,僅僅添加相應的依賴到你的DOM文件里,如下所示:
...
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.1.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.2.0.ga</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
...
下一步是獲得一個Hibernate Session 工廠.利用Hibernate Annotations與不使用它創(chuàng)建Hibernate session工廠有一點不同,雖然不需要大幅度修改.你只需須簡單地使用AnnotationConfiguration類安裝你的session工廠:
sessionFactory
=new AnnotationConfiguration().buildSessionFactory();
一般的,你需要通過<mapping>元素在Hibernate配置文件里(hibernate.cfg.xml)聲明持久化類
<hibernate-configuration>
<session-factory>
<mapping class="com.onjava.modelplanes.domain.PlaneType"/>
<mapping class="com.onjava.modelplanes.domain.ModelPlane"/>
</session-factory>
</hibernate-configuration>
如今許多java 工程都使用輕量級的程序框架例如Spring.如果你正在用Spring框架,你可以容易地利用AnnotationSessionFactory類裝配一個基于Annotations 的Hibernate Session Factory,如下:
<!-- Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.DerbyDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
...
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.onjava.modelplanes.domain.PlaneType</value>
<value>com.onjava.modelplanes.domain.ModelPlane</value>
...
</list>
</property>
</bean>
我們第一個持久化類現(xiàn)在我們知道如何獲得基于Annotation的Hibernate Session ,讓我們看看這個注解的持久化類看起來像什么樣子.
被注解的持久化類是一般的POJO類,就像在其他Hibernate程序里的一樣.好的,差不多了.你需要依賴于Java 持久化API (javax.persistence.*),并且還需要導入注解包類(org.hibernate.annotations.*)如果你使用了任何Hibernate擴展的話.但是除此之外,他們僅僅是擁有持久化相關注解的POJO.這有個例子:
@Entity
public class ModelPlane {
private Long id;
private String name;
@Id
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
如我們所言,非常簡單.@Entity注解聲明類將被持久化.@Id注解讓你指示持久化類的唯一性標識屬性.實際上,你可以持久化字段(注解成員變量)或者持久化屬性(通過注釋getter方法.在這篇文章的剩余部分,我們將用基于屬性的注解.關于基于注解的持久化一個好處是他的缺省行為.例如.你不需要聲明每一個屬性是否要被持久化-任何屬性都假定將被持久化除非用@Transient注解了他. 對代碼來說這是簡單的,并且相對于舊的XML配置文件來說,也節(jié)省了很多打字量.
生成主鍵Hibernate一個擅長的功能是主鍵自動生成,Hibernate/EJB 3注解也為主鍵自動生成提供了豐富的支持,允許諸多生成策略.下面例子演示了最常見的用途,這里Hibernate 根據(jù)數(shù)據(jù)庫給出一個合適的主鍵生成策略.
@Id
@GeneratedValue (strategy=GenerationType.AUTO)
public Long getId() {
return id;
}
自定義表和字段映射默認情況下,Hibernate將映射持久化類到表,用匹配的字段名映射.例如,上面的類將經(jīng)由下列SQL語句映射到表:
CREATE TABLE MODELPLANE
(
ID long,
NAME varchar
)
如果你自己生成和維護數(shù)據(jù)庫的話非常好,并且使你的代碼易于維護.然而,他不適合所有需求.有些程序需要訪問外部數(shù)據(jù)庫,并且可能需要公司數(shù)據(jù)庫命名轉換.如果需要的話,你可以使用@Table和@Column注解進行你的持久化映射:
@Entity
@Table(name="T_MODEL_PLANE")
public class ModelPlane {
private Long id;
private String name;
@Id
@Column(name="PLANE_ID")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name="PLANE_NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
它將映射到下面的表
CREATE TABLE T_MODEL_PLANE
(
PLANE_ID long,
PLANE_NAME varchar
)
你可以利用Table和Column屬性自定義映射.它可讓你指定諸如列長度,not-null約束等等,hibernate支持大量的屬性注解:
...
@Column(name="PLANE_ID", length=80, nullable=true)
public String getName() {
return name;
}
…
映射關系Java持久化映射中一個最重要,最復雜的部分是確定怎么映射表間的關系.如其他的特性一樣,Hibernate在這方面也提供了大量的靈活性,但是以增加了某種復雜度為代價的.我們將瀏覽一系列共同的用例以對如何使用注解有個大體認識.
最常用的一個關系是many-to-one關系.假定在上面的例子中,每個ModelPlane經(jīng)由many-to-one關系被關聯(lián)到一個PlaneType (換句話說每個Model plane 被確切的關聯(lián)到一個 plane type,通過給定一個plane type可以被關聯(lián)到多個 model plane ),你可以映射如下:
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
public PlaneType getPlaneType() {
return planeType;
}
這個CascadeType值表示Hibernate將怎么進行級聯(lián)操作
另外一個常用的關系是與上面相對的:one-to-many關系,也以集合而聞名,集合將映射變得有些復雜,在舊的和新的注解中,并且我們將撇開表面細節(jié)直接給你完成的例子以給你一個大概,例如在上面例子中,每一個PlaneType對象可能包含一個ModelPlane的集合,可以映射如下:
@OneToMany(mappedBy="planeType",
cascade=CascadeType.ALL,
fetch=FetchType.EAGER)
@OrderBy("name")
public List<ModelPlane> getModelPlanes() {
return modelPlanes;
}
命名查詢Hibernate一個優(yōu)秀的特征是可以在映射文件申明命名查詢的能力.這些查詢可以通過名字在代碼里調用,這可以讓你集中查詢且避免有sql或者Hql代碼分散在程序里.
你也可以通過注解,利用@NameQueries和@NameQuery注解,如下:
@NamedQueries(
{
@NamedQuery(
name="planeType.findById",
query="select p from PlaneType p left join fetch p.modelPlanes where id=:id"
),
@NamedQuery(
name="planeType.findAll",
query="select p from PlaneType p"
),
@NamedQuery(
name="planeType.delete",
query="delete from PlaneType where id=:id"
)
}
)
一旦定義,可以可以調用正如其他命名查詢.
總結Hibernate 3注解提供了一個強大而優(yōu)雅的API來簡化java數(shù)據(jù)庫持久化代碼,在這里我們僅僅涉及到表面的知識,你選擇貼近標準,并且利用java持久化API或者收益于Hibernate的規(guī)范擴展, 在以失去某種輕便性為代價的基礎上,它提供了更為強大靈活的功能.不管怎么