`

Hibernate 3注释简介

阅读更多

在过去几年里,Hibernate不断发展,几乎成为Java数据库持久性的事实标准。它非常强大、灵活,而且具备了优异的性能。在本文中,我们将了解如何使用Java 5 注释来简化Hibernate代码,并使持久层的编码过程变得更为轻松。

  传统上,Hibernate的配置依赖于外部 XML 文件:数据库映射被定义为一组 XML 映射文件,并且在启动时进行加载。创建这些映射有很多方法,可以从已有数据库模式或Java类模型中自动创建,也可以手工创建。无论如何,您最终将获得大量的 Hibernate 映射文件。此外,还可以使用工具,通过javadoc样式的注释生成映射文件,尽管这样会给您的构建过程增加一个步骤。

  在最近发布的几个Hibernate版本中,出现了一种基于 Java 5 注释的更为巧妙的新方法。借助新的 Hibernate Annotation 库,即可一次性地分配所有旧映射文件——一切都会按照您的想法来定义——注释直接嵌入到您的 Java 类中,并提供一种强大及灵活的方法来声明持久性映射。籍由自动代码完成和语法突出显示功能,最近发布的Java IDE也为其提供了有力的支持。

  Hibernate Annotation还支持新的 EJB 3 持久性规范。这些规范旨在提供一种标准化的 Java 持久性机制。由于 Hibernate 3 还提供了一些扩展,因此您可以十分轻松地遵从这些标准,并使用 EJB 3 编程模型来对 Hibernate 持久层进行编码。

  现在,让我们来动手使用Hibernate Annotation。

安装 Hibernate Annotation

  要使用 Hibernate Annotation,您至少需要具备 Hibernate 3.2和Java 5。可以从 Hibernate 站点 下载 Hibernate 3.2 和 Hibernate Annotation库。除了标准的 Hibernate JAR 和依赖项之外,您还需要 Hibernate Annotations .jar 文件(hibernate-annotations.jar)、Java 持久性 API (lib/ejb3-persistence.jar)。如果您正在使用 Maven,只需要向 POM 文件添加相应的依赖项即可,如下所示:

 ...

org.hibernate
hibernate
3.2.1.ga


org.hibernate
hibernate-annotations
3.2.0.ga


javax.persistence
persistence-api
1.0

...

  下一步就是获取 Hibernate 会话工厂。尽管无需惊天的修改,但这一工作与使用 Hibernate Annotations有所不同。您需要使用 AnnotationConfiguration 类来建立会话工厂:

sessionFactory = new

AnnotationConfiguration().buildSessionFactory();

  尽管通常使用 元素来声明持久性类,您还是需要在 Hibernate 配置文件(通常是 hibernate.cfg.xml)中声明持久性类:






  近期的许多 Java 项目都使用了轻量级的应用框架,例如 Spring。如果您正在使用 Spring 框架,可以使用 AnnotationSessionFactoryBean 类轻松建立一个基于注释的 Hibernate 会话工厂,如下所示:

<!-- Hibernate session factory -->






org.hibernate.dialect.DerbyDialect
create
...




com.onjava.modelplanes.domain.PlaneType
com.onjava.modelplanes.domain.ModelPlane
...



第一个持久性类

  既然已经知道了如何获得注释所支持的 Hibernate 会话,下面让我们来了解一下带注释的持久性类的情况:

  像在其他任何 Hibernate应用程序中一样,带注释的持久性类也是普通 POJO。差不多可以说是。您需要向 Java 持久性 API (javax.persistence.*)添加依赖项,如果您正在使用任何特定于 Hibernate的扩展,那很可能就是 Hibernate Annotation 程序包(org.hibernate.annotations.*),但除此之外,它们只是具备了持久性注释的普通 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方法)的持久性。后文中将使用基于属性的注释。基于注释的持久性的优点之一在于大量使用了默认值(最大的优点就是 “惯例优先原则(convention over configuration)”)。例如,您无需说明每个属性的持久性——任何属性都被假定为持久的,除非您使用 @Transient 注释来说明其他情况。这简化了代码,相对使用老的 XML 映射文件而言也大幅地减少了输入工作量。

生成主键

  Hibernate 能够出色地自动生成主键。Hibernate/EBJ 3 注释也可以为主键的自动生成提供丰富的支持,允许实现各种策略。下面的示例说明了一种常用的方法,其中 Hibernate 将会根据底层数据库来确定一种恰当的键生成策略:

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
return id;
}

定制表和字段映射

  默认情况下,Hibernate 会将持久类以匹配的名称映射到表和字段中。例如,前一个类可以与映射到以如下代码创建的表中:

CREATE TABLE MODELPLANE
(
ID long,
NAME varchar
)

  如果您是自己生成并维护数据库,那么这种方法很有效,通过省略代码可以大大简化代码维护。然而,这并不能满足所有人的需求。有些应用程序需要访问外部数据库,而另一些可能需要遵从公司的数据库命名惯例。如果有必要,您可以使用 @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
)

  也可以使用其他图和列的属性来定制映射。这使您可以指定诸如列长度、非空约束等详细内容。Hibernate支持大量针对这些注释的属性。下例中就包含了几种属性:

 ...
@Column(name="PLANE_ID", length=80, nullable=true)
public String getName() {
return name;
}
...

映射关系

  Java 持久性映射过程中最重要和最复杂的一环就是确定如何映射表间的关系。像其他产品一样, Hibernate 在该领域中提供了高度的灵活性,但却是以复杂度的增加为代价。我们将通过研究几个常见案例来了解如何使用注释来处理这一问题。

  其中一种最常用的关系就是多对一的关系。假定在以上示例中每个 ModelPlane 通过多对一的关系(也就是说,每个飞机模型只与一种飞机类型建立联系,尽管指定的飞机类型可以与七种飞机模型建立联系)来与 PlaneType 建立联系。可如下进行映射:

 @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
public PlaneType getPlaneType() {
return planeType;
}

  CascadeType 值表明 Hibernate 应如何处理级联操作。

  另一种常用的关系与上述关系相反:一对多再对一关系,也称为集合。在老式的 Hibernate 版本中进行映射或使用注释时,集合令人头疼,这里我们将简要加以探讨,以使您了解如何处理集合,例如,在以上示例中每个 PlaneType 对象都可能会包含一个 ModelPlanes 集合。可映射如下:

 @OneToMany(mappedBy="planeType",
cascade=CascadeType.ALL,
fetch=FetchType.EAGER)
@OrderBy("name")
public List getModelPlanes() {
return modelPlanes;
}

命名查询

  Hibernate 最优秀的功能之一就在于它能够在您的映射文件中声明命名查询。随后即可通过代码中的名称调用此类查询,这使您可以专注于查询,而避免了 SQL 或者 HQL 代码分散于整个应用程序中的情况。

  也可以使用注释来实现命名查询,可以使用 @NamedQueries 和 @NamedQuery 注释,如下所示:

@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 注释提供了强大而精致的 API,简化了 Java 数据库中的持久性代码,本文中只进行了简单的讨论。您可以选择遵从标准并使用 Java 持久性 API,也可以利用特定于 Hibernate的扩展,这些功能以损失可移植性为代价提供了更为强大的功能和更高的灵活性。无论如何,通过消除对 XML 映射文件的需求,Hibernate 注释将简化应用程序的维护,同时也可以使您对EJB 3 有初步认识。来试试吧!

posted @ 2009-07-26 14:00 jiafang83 阅读(23) | 评论 (0)编辑 收藏

摘自:http://www.iteye.com/topic/95822

school和userMember是一对多关系:

SchoolInfo.java

 1import javax.persistence.CascadeType;   
 2import javax.persistence.Column;   
 3import javax.persistence.Entity;   
 4import javax.persistence.FetchType;   
 5import javax.persistence.GeneratedValue;   
 6import javax.persistence.Id;   
 7import javax.persistence.OneToMany;   
 8import javax.persistence.Table;   
 9import javax.persistence.Temporal;   
10import javax.persistence.TemporalType;   
11   
12import org.hibernate.annotations.Formula;   
13import org.hibernate.annotations.GenericGenerator;   
14   
15@Entity   
16@Table(name = "school_info")   
17public class SchoolInfo implements java.io.Serializable {   
18   
19    @Id   
20    @GeneratedValue(generator = "system-uuid")   
21    @GenericGenerator(name = "system-uuid", strategy = "uuid")   
22    private String id;//hibernate的uuid机制,生成32为字符串   
23   
24    @Column(name = "actcodeId", updatable = false, nullable = true, length = 36)   
25    private String actcodeId;   
26   
27    @Formula("select COUNT(*) from school_info")   
28    private int count;   
29   
30    @Temporal(TemporalType.TIMESTAMP)//不用set,hibernate会自动把当前时间写入   
31    @Column(updatable = false, length = 20)   
32    private Date createTime;   
33   
34    @Temporal(TemporalType.TIMESTAMP)   
35    private Date updateTime;// 刚开始我默认insertable=false,但会读取出错提示如下:   
36    // Value '0000-00-00' can not be represented as java.sql.Timestamp   
37   
38    // mappedBy="school"就相当于inverse=true,(mappedBy指定的是不需要维护关系的一端)   
39    // 应该注意的是mappedBy值对应@ManyToOne标注的属性,我刚开始写成"schoolId",让我郁闷了好一会 
40    @OneToMany(mappedBy = "school", cascade = CascadeType.ALL, fetch = FetchType.EAGER, targetEntity = UserMember.class)   
41    // 用范性的话,就不用targetEntity了   
42    private List<usermember> users = </usermember>new ArrayList<usermember>();  </usermember> 
43       
44}
   
45


@GeneratedValue(strategy=GenerationType.AUTO)我们常用的自增长机制,我这里采用的是hibernate的uuid生成机制.
需要注意的是import javax.xx.Entity ,而不是org.hibernate.xx.Entity。

郁闷的是我上面用到@Formula,生成的sql竟然是'select COUNT(*) from school_info as formula0_ from school_info schoolinfo0_,当然不能执行了,寻求正解中~!!!!!!!!!

UserMember.java(前面引入的包已经贴过了,下面就不贴了)

 1 @Entity   
 2 @Table(name = "teacher_info")//实体类和数据库表名不一致时,才用这个   
 3 public class UserMember implements java.io.Serializable {   
 4    
 5     @Id   
 6     @GeneratedValue(generator = "system-uuid")   
 7     @GenericGenerator(name = "system-uuid", strategy = "uuid")   
 8     private String id;   
 9    
10     @Column(updatable = false, nullable = false, length = 20)   
11     private String logonName;   
12        
13     @Temporal(TemporalType.TIMESTAMP)   
14     @Column(updatable = false, length = 20)   
15     private Date createTime;   
16    
17     @Temporal(TemporalType.TIMESTAMP)   
18     private Date updateTime;   
19    
20     @ManyToOne(cascade = { CascadeType.MERGE })   
21     @JoinColumn(name = "schoolId")   
22     private SchoolInfo school;   
23     //注意该类就不用声明schoolId属性了,如果不用@JoinColumn指明关联的字段,hibernate默认会是school_id.   
24    
25 }   

 

分享到:
评论
1 楼 beykery 2012-01-31  
createTime这个字段并不会在保持bean的时候自动写到数据库里,不知道你的数据库是什么,我用的mysql,在数据库里生成的类型是DATATIME不是时间戳。

相关推荐

    hibernate注释详解

    hibernate注释详解 内含hibernate各种注释说明

    Hibernate注释方法描述数据库映射

    ### Hibernate注释方法描述数据库映射 #### 一、概述 Hibernate 是一款强大的对象关系映射(ORM)框架,它简化了 Java 开发者与数据库交互的过程。在 Hibernate 中,可以利用注解来描述实体类与数据库表之间的映射...

    Spring+Struts2+Hibernate3 注释的例子

    这个“Spring+Struts2+Hibernate3 注释的例子”应该是一个教学或者示例项目,用于演示如何将这三个框架整合到一个应用中。 Spring框架是一个全面的后端开发框架,提供了依赖注入(DI)和面向切面编程(AOP)等功能...

    Hibernate注释深入解析

    【Hibernate注释深入解析】 在Java开发中,Hibernate是一个广泛使用的对象关系映射(ORM)框架,它允许开发者使用面向对象的方式操作数据库。在Hibernate中,注释是一种强大的工具,可以简化配置,使得代码更加简洁...

    hibernate3 注释生成复合主键或者嵌入式主键的方法及实例.doc

    在Hibernate3中,虽然XML配置文件是主要的元数据来源,但随着版本的升级,Annotation逐渐成为更便捷的方式来描述实体类与数据库表之间的映射关系。这篇文档将介绍如何使用Hibernate注解来生成复合主键或嵌入式主键。...

    Hibernate-tools解决hbm.xml中文注释乱码和生成实体类注释

    总结,`Hibernate-tools`是Hibernate生态中不可或缺的一部分,它极大地提高了开发效率,同时也为处理中文注释提供了有效方案。通过合理配置和使用,我们可以避免乱码问题,并生成符合规范的带有丰富注释的实体类代码...

    hibernate注释源程序

    **hibernate注释源程序详解** 在Java领域,Hibernate是一个非常重要的对象关系映射(ORM)框架,它简化了数据库操作,使开发者能够用Java对象来操作数据库。本篇文章将深入探讨Hibernate中的注释(Annotation)使用...

    Hibernate使用注释

    使用hibernate注释的核心优点是我们不需要创建映射(*.hbm.xml)文件直接创建对象关联。 在这里,hibernate注释用于提供元数据。步骤如下: 1.为MySQL添加连接驱动程序的jar文件(如果数据库是MySQL)和注释2.创建持久化...

    hibernate@注解方式配置实体类,调用javadoc接口生成数据库表及字段的注释说明

    hibernate@注解方式配置实体类时,利用javadoc接口生成数据库表及字段的注释说明,支持oracle、sqlserver、db2、mysql数据库。因用到java\lib\tools.jar,需要将该jar放入工程lib下(或者tomcat\lib下、或加入...

    Hibernate注释大全收藏

    ### Hibernate注释大全收藏 #### 一、声明实体Bean `@Entity` 注解用于标记一个Java类作为Hibernate中的实体Bean。例如: ```java @Entity public class Flight implements Serializable { Long id; @Id public...

    基于Maven,Struts2, Spring,Hibernate全注释的开发框架

    使用Maven3.0.5, Struts2, Spring, Hibernate3, annotation实现零配置的开发框架.里面有详细的开发指导文档, 后台用googlecode的 hibernate-generic-dao - Generic DAO 和 Search的代码,完全进行封装. 由于Generic ...

    Hibernate 注释语法.chm

    Hibernate 注释语法的简单讲解,个人的学习总结笔记

    Hibernate注解、注释大全

    3. `@Table`:此注解用于指定实体Bean对应的数据库表名,可选地包含schema和catalog。例如: ```java @Entity@Table(name="tbl_sky") public class Sky implements Serializable {...} ``` 4. `@UniqueConstraint`...

    hibernate中的注释的几种配置方式

    在探讨Hibernate中注释的几种配置方式时,我们主要聚焦于如何通过注解来定义实体类与数据库表之间的映射关系,以及如何在Spring框架下整合Hibernate,利用注解进行SessionFactory的配置。以下是对给定内容中涉及的...

    Hibernate注释

    以上就是关于Hibernate注释的基本知识,它们在Java对象和数据库表之间的映射中起着至关重要的作用,简化了开发过程,并提供了更灵活的持久化管理。通过合理使用这些注解,开发者能够有效地控制对象的生命周期,处理...

    hibernate中的注释学习,以及注释帮助

    一、Hibernate注释基础 1. `@Entity`: 这个注释标记一个Java类为持久化实体,意味着这个类的实例将在数据库中有一个对应的表。例如: ```java @Entity public class User { // ... } ``` 这会告诉Hibernate,User...

    《Hibernate 3 API参考手册》-电子文档下载(PDF)

    在描述中提到的“配合Hibernate 3中文参考使用”,意味着此手册可能包含有中文翻译或注释,这对于中文使用者来说是极大的便利,能够帮助他们更好地理解和应用Hibernate 3的API。 关于Hibernate 3 API,它是...

    annotation(注释)版本的hibernate

    《注释驱动的Hibernate实战详解》 在Java的持久化框架中,Hibernate以其强大的功能和易用性,深受开发者喜爱。然而,随着Java技术的发展,传统的XML配置方式逐渐被注解(Annotation)所取代,使得代码更加简洁、...

    学习struts2,hibernate3(jpa注释编程),spring2,ajax的经典项目.rar

    学习struts2,hibernate3(jpa注释编程),spring2,ajax的经典项目.rar 学习struts2,hibernate3(jpa注释编程),spring2,ajax的经典项目.rar

    hibernate注解所需包

    使用hibernate注解,必须要使用库hibernate-commons-annotations,hibernate-core,hibernate-jpa,ejb3-persistence,javassist等

Global site tag (gtag.js) - Google Analytics