annotation的官方文档
以下所有参考都来自官方文档。在官方下载的包中。比如hibernate-annotations-3.4.0.GA\doc\reference\zh_cn\html_single
annotaiton与hbm.xml的优先级
不能多次声明同一个类(要么通过注解要么通过hbm.xml配置文件), 而且在一个映射实体的类继承层次中,这两个配置策略不能同时使用.
为了简化从hbm文件到注解的迁移过程, 配置机制将自动检测在注解和hbm文件中重复的映射。 默认情况下hbm文件中的声明比类中的注解元数据具有更高的优先级。 这种优先级的设定是以类为单位的。 你也可以通过hibernate.mapping.precedence修改这种优先级。 默认的值是hbm, class, 如果改为class,hbm,当发生冲突的时候,类中的注解将比hbm文件具有更高的优先级。
EJB3注解
EJB3注解的API定义在javax.persistence.*包里面. 大部分和JDK5兼容的IDE(象Eclipse, IntelliJ IDEA 和Netbeans等等)都提供了注解接口和属性的自动完成功能. (这些不需要IDE提供特别的EJB3支持模块,因为EJB3注解是标准的JDK5注解)。所以,在hibernate中使用注解时引入的包需为javax.persistence.x*.
声明实体bean
每一个持久化POJO(plain ordinary java object)类都是一个实体bean,这可以通过在类的定义中使用@Entity注解来进行声明:
@Entity public class Flight implements Serializable { Long id; @Id public Long getId() { return id; } public void setId(Long id) { this.id = id; } }
通过@Entity注解将一个类声明为一个实体bean(即一个持久化POJO类), @Id注解则声明了该实体bean的标识属性. 其他的映射定义是隐式的.这种以隐式映射为主体,以显式映射为例外的配置方式在新的EJ3规范中处于非常重要的位置, 和以前的版本相比有了质的飞跃. xml文档时以显示定义为主的!在上面这段代码中:Flight类映射到Flight表,并使用id列作为主键列.
在对一个类进行注解时,你可以选择对它的的属性或者方法进行注解,根据你的选择,Hibernate的访问类型分别为 field或property. EJ3规范要求在需要访问的元素上进行注解声明,例如,如果访问类型为 property就要在getter方法上进行注解声明, 如果访问类型为 field就要在字段上进行注解声明.应该尽量避免混合使用这两种访问类型. Hibernate根据@Id 或@EmbeddedId的位置来判断访问类型.
显示声明映射表和表的字段(一般在类名和表名不同的时候使用)
@Table是类一级的注解, 通过@Table注解可以为实体bean映射指定表(table),目录(catalog)和schema的名字. 如果没有定义@Table,那么系统自动使用默认值:实体的短类名(不附带包名).
@Entity @Table(name="tbl_sky") public class Sky implements Serializable { ...
声明基本的属性映射
所有没有定义注解的属性等价于在其上面添加了@Basic注解.Hibernate和EJB3都支持所有基本类型(基本类型共有八种,它们分别都有相对应的包装类,byte,short,int,long,char,boolean,float,double)的属性映射. 这些基本类型包括所有的Java基本类型,及其各自的wrapper类和serializable类.
声明列属性(一般在属性名和列名不同时使用)
使用 @Column 注解可将属性映射到列.
@Entity public class Flight implements Serializable { ... @Column(updatable = false, name = "flight_name", nullable = false, length=50) public String getName() { ... }
在上面这个例子中,name属性映射到flight_name列.name 可选,列名(默认值是属性名)
嵌入式对象
在实体中可以定义一个嵌入式组件(embedded component), 甚至覆盖该实体中原有的列映射. 组件类必须在类一级定义@Embeddable注解. 在特定的实体的关联属性上使用@Embedded和@AttributeOverride注解可以覆盖该属性对应的嵌入式对象的列映射:
实体Bean:
@Entity public class Person implements Serializable { // Persistent component using defaults Address homeAddress; @Embedded @AttributeOverrides( { @AttributeOverride(name="iso2", column = @Column(name="bornIso2") ), @AttributeOverride(name="name", column = @Column(name="bornCountryName") ) } ) Country bornIn; ... }
实体组件:
@Embeddable public class Address implements Serializable { String city; Country nationality; //no overriding here } @Embeddable public class Country implements Serializable { private String iso2; @Column(name="countryName") private String name; public String getIso2() { return iso2; } public void setIso2(String iso2) { this.iso2 = iso2; } public String getName() { return name; } public void setName(String name) { this.name = name; } ... }
实体bean Person 有两个组件属性, 分别是homeAddress和bornIn. 我们可以看到homeAddress 属性并没有注解. 但是Hibernate自动检测其对应的Address类中的@Embeddable注解, 并将其看作一个持久化组件.对于Country中已映射的属性, 则使用@Embedded和@AttributeOverride 注解来覆盖原来映射的列名. 正如你所看到的, Address对象中还内嵌了Country对象, 这里和homeAddress一样使用了Hibernate和EJB3自动检测机制. 目前EJB3规范还不支持覆盖多层嵌套(即嵌入式对象中还包括其他嵌入式对象)的列映射. 不过Hibernate通过在表达式中使用"."符号表达式提供了对此特征的支持.
无注解之属性的默认值
如果某属性没有注解,该属性将遵守下面的规则:
- 如果属性为单一类型,则映射为@Basic
- 否则,如果属性对应的类型定义了@Embeddable注解,则映射为@Embedded
- 否则,如果属性对应的类型实现了Serializable, 则属性被映射为@Basic并在一个列中保存该对象的serialized版本
- 否则,如果该属性的类型为java.sql.Clob 或 java.sql.Blob,则作为@Lob并映射到适当的LobType.
映射主键属性
使用@Id注解可以将实体bean中的某个属性定义为标识符(identifier). 该属性的值可以通过应用自身进行设置, 也可以通过Hiberante生成(推荐). 使用 @GeneratedValue注解可以定义该标识符的生成策略:
- AUTO - 可以是identity column类型,或者sequence类型或者table类型,取决于不同的底层数据库.
- TABLE - 使用表保存id值
- IDENTITY - identity column
- SEQUENCE - sequence
和EJB3规范相比,Hibernate提供了更多的id生成器