类级映射:实体和值对象

可以被持久化的类包括实体和值对象两大类。

一、实体映射

通过给一个类添加@Entity逻辑注解,告知JPA这是一个可以持久化的实体类。

请注意@Entity逻辑注解不可以继承。这意味着如果如果父类和子类都是实体类,那么就需要分别在父类和子类上都添加@Entity,子类不能通过从父类继承这个注解而自动成为实体类。

实体类上还可以添加可选的@Table物理映射,表明需要将实体映射到的数据库表。这个注解有一个name属性,用于指定表名。

如果不添加@Table映射,JPA默认将实体类映射到同名的数据库表中。出于下面的两个原因,我倾向于为每个实体类添加@Table注解:

  • 由多个单词组成的实体类(例如实体类名OrderLine就是由两个单词OrderLine组成)可以通过驼峰式命名风格在视觉上明显区分多个组成词汇。但某些数据库如Oracle会采用全大写形式(例如ORDERLINE)命名表,这样多个单词就无法在视觉上分辨出来。我喜欢给数据库表明确命名,用下划线分隔单词(例如ORDER_LINES
  • 数据表是记录的集合,用复数的形式命名表更加具有现实意义。当JPA实现框架在后台生成和显示SQL语句时,“SELECT * FROM ORDERLINE”明显不如“SELECT * FROM ORDER_LINES”更加具有表达性。

如果在persistence.xml中将Hibernate属性hibernate.hbm2ddl.auto配置为非none的值,Hibernate第一次启动时将会根据实体类上提供的映射元数据自动生成数据库表结构。

下面是实体类Order的类级映射:

@Entity
@Table(name = "orders")
public class Order extends BaseEntity {
  ...
}

二、值对象映射

通过给一个类添加@Embeddable逻辑注解,告知JPA这是一个可持久化的值对象。下面是值对象Address的类级映射:

@Embeddable
public class Address {
  ...
}

也可以不在值对象类级添加@Embeddable逻辑注解,而是在值对象作为另一个实体的单值属性(例如值对象Address作为实体OrdershippingAddress属性类型)时,在实体属性上添加@Embedded逻辑注解,告知JPA实体的这个属性的类型是一个值对象。例如:

@Entity
@Table(name = "orders")
public class Order extends BaseEntity {

  @Embedded
  private Address shippingAddress;
}

请务必牢记Embeddable是类级注解,用于标记值对象类;而@Embedded是属性级注解,用于标注实体类的某个属性,其类型是单值的值对象。二者不需要同时存在。我倾向于在属性上上注解Embedded

results matching ""

    No results matching ""