我是一个Java爱好者
分类:
2010-04-19 13:37:14
声明实体Bean
@Entity
public class Flight implements Serializable {
}
@Entity 注解将一个类声明为实体 Bean, @Id 注解声明了该实体Bean的标识属性。
Hibernate 可以对类的属性或者方法进行注解。属性对应field类别,方法的 getXxx()对应property类别。
定义表
通过 @Table 为实体Bean指定对应数据库表,目录和schema的名字。
@Entity
@Table(name="tbl_sky")
public class Sky implements Serializable {
...
@Table 注解包含一个schema和一个catelog 属性,使用@UniqueConstraints 可以定义表的唯一约束。
@Table(name="tbl_sky",
)
上述代码在
@Version 注解用于支持乐观锁版本控制。
@Entity
public class Flight implements Serializable {
}
version属性映射到 "OPTLOCK" 列,entity manager 使用这个字段来检测冲突。 一般可以用 数字 或者 timestamp 类型来支持 version.
实体Bean中所有非static 非 transient 属性都可以被持久化,除非用@Transient注解。
默认情况下,所有属性都用 @Basic 注解。
public transient int counter; //transient property
private String firstname; //persistent property
@Transient
String getLengthInMeter() { ... } //transient property
String getName() {... } // persistent property
@Basic
int getLength() { ... } // persistent property
@Basic(fetch = FetchType.LAZY)
String getDetailedComment() { ... } // persistent property
@Temporal(TemporalType.TIME)
java.util.Date getDepartureTime() { ... } // persistent property
@Enumerated(EnumType.STRING)
Starred getNote() { ... } //enum persisted as String in database
上述代码中 counter, lengthInMeter 属性将忽略不被持久化,而 firstname, name, length 被定义为可持久化和可获取的。
@TemporalType.(DATE,TIME,TIMESTAMP) 分别Map java.sql.(Date, Time, Timestamp).
@Lob 注解属性将被持久化为 Blog 或 Clob 类型。具体的java.sql.Clob, Character[], char[] 和 java.lang.String 将被持久化为 Clob 类型. java.sql.Blob, Byte[], byte[] 和 serializable type 将被持久化为 Blob 类型。
@Lob
public String getFullText() {
}
@Lob
public byte[] getFullCode() {
}
@Column 注解将属性映射到列。
@Entity
public class Flight implements Serializable {
定义 name 属性映射到 flight_name column, not null, can't update, length equal 50
@Column(
嵌入式对象(又称组件)也就是别的对象定义的属性
组件类必须在类一级定义 @Embeddable 注解。在特定的实体关联属性上使用 @Embeddable 和 @AttributeOverride 注解可以覆盖该属性对应的嵌入式对象的列映射。
@Entity
public class Person implements Serializable {
}
@Embeddable
public class Address implements Serializable {
}
@Embeddable
public class Country implements Serializable {
}
Person 类定义了 Address 和
无注解属性默认值:
• 属性为简单类型,则映射为 @Basic
• 属性对应的类型定义了 @Embeddable 注解,则映射为 @Embedded
• 属性对应的类型实现了Serializable,则属性被映射为@Basic并在一个列中保存该对象的serialized版本。
• 属性的类型为 java.sql.Clob or java.sql.Blob, 则映射到 @Lob 对应的类型。
映射主键属性
@Id 注解可将实体Bean中某个属性定义为主键,使用@Generatue注解可以定义该标识符的生成策略。
• AUTO -
• TABLE - 使用table保存id值
• IDENTITY - identity column
• SEQUENCE - seque
nce
@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_STORE")
public Integer getId() { ... }
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId() { ... }
AUTO 生成器,适用与可移值的应用,多个@Id可以共享同一个 identifier生成器,只要把generator属性设成相同的值就可以。通过@SequenceGenerator 和 @TableGenerator 可以配置不同的 identifier 生成器。
//and the annotation equivalent
@javax.persistence.TableGenerator(
)
//and the annotation equivalent
@javax.persistence.SequenceGenerator(
)
The next example shows the definition of a sequence generator in a class scope:
@Entity
@javax.persistence.SequenceGenerator(
)
public class Store implements Serializable {
}
Store类使用名为my_sequence的sequence,并且SEQ_STORE生成器对于其他类是不可见的。
通过下面语法,你可以定义组合键。
• 将组件类注解为 @Embeddable, 并将组件的属性注解为 @Id
• 将组件的属性注解为 @EmbeddedId
• 将类注解为 @IdClass,并将该实体中所有主键的属性都注解为 @Id
@Entity
@IdClass(FootballerPk.class)
public class Footballer {
}
@Embeddable
public class FootballerPk implements Serializable {
}
@Entity
@AssociationOverride( name="id.channel", joinColumns = @JoinColumn(name="chan_id") )
public class TvMagazin {
}
@Embeddable
public class TvMagazinPk implements Serializable {
}
映射继承关系
EJB支持3种类型的继承。
• Table per Class Strategy: the
• Single Table per Class Hierarchy Strategy: the
• Joined Subclass Strategy: the
@Inheritance 注解来定义所选的之类策略。
每个类一张表
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Flight implements Serializable {
有缺点,如多态查询或关联。Hibernate 使用 SQL Union 查询来实现这种策略。这种策略支持双向的一对多关联,但不支持 IDENTIFY 生成器策略,因为ID必须在多个表间共享。一旦使用就不能使用AUTO和IDENTIFY生成器。
每个类层次结构一张表
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
)
@DiscriminatorValue("Plane")
public class Plane { ... }
@Entity
@DiscriminatorValue("A320")
public class A320 extends Plane { ... }
整个层次结构中的所有父类和子类属性都映射到同一个表中,他们的实例通过一个辨别符列(discriminator)来区分。
Plane 是父类。@DiscriminatorColumn 注解定义了辨别符列。对于继承层次结构中的每个类, @DiscriminatorValue 注解指定了用来辨别该类的值。 辨别符列名字默认为 DTYPE,其默认值为实体名。其类型为DiscriminatorType.STRING。
连接的子类
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class Boat implements Serializable { ... }
@Entity
public class Ferry extends Boat { ... }
@Entity
@PrimaryKeyJoinColumn(name="BOAT_ID")
public class AmericaCupClass extends Boat { ... }
以上所有实体使用 JOINED 策略 Ferry和Boat class使用同名的主键关联(eg: Boat.id = Ferry.id), AmericaCupClass 和 Boat 关联的条件为 Boat.id = AmericaCupClass.BOAT_ID.
从父类继承的属性
@MappedSuperclass
public class BaseEntity {
}
@Entity class Order extends BaseEntity {
}
继承父类的一些属性,但不用父类作为映射实体,这时候需要 @MappedSuperclass 注解。上述实体映射到数据库中的时候对应 Order 实体Bean, 其具有 id, lastUpdate, lastUpdater 三个属性。如果没有@MappedSuperclass 注解,则父类中属性忽略,这是 Order 实体 Bean 只有 id 一个属性。
映射实体Bean的关联关系
一对一
使用 @OneToOne 注解可以建立实体Bean之间的一对一关系。一对一关系有3种情况。
• 关联的实体都共享同样的主键。
@Entity
public class Body {
}
@Entity
public class Heart {
}
通过@PrimaryKeyJoinColumn 注解定义了一对一的关联关系。
多对一
使用 @ManyToOne 注解定义多对一关系。
@Entity()
public class Flight implements Serializable {
}
其中@JoinColumn 注解是可选的,关键字段默认值和一对一关联的情况相似。列名为:主题的关联属性名 + 下划线 + 被关联端的主键列名。本例中为company_id,因为关联的属性是company, Company的主键为 id.
@ManyToOne 注解有个targetEntity属性,该参数定义了目标实体名。通常不需要定义,大部分情况为默认值。但下面这种情况则需要 targetEntity 定义(使用接口作为返回值,而不是常用的实体)。
@Entity()
public class Flight implements Serializable {
}
public interface Company {
多对一也可以通过关联表的方式来映射,通过 @JoinTable 注解可定义关联表。该关联表包含指回实体的外键(通过@JoinTable.joinColumns)以及指向目标实体表的外键(通过@JoinTable.inverseJoinColumns).
@Entity()
public class Flight implements Serializable {
}