博客首页 注册 建议与交流 排行榜 加入友情链接
推荐 投诉 搜索: 帮助

翔的窝窝

现在的付出只为明天我能做我喜欢做的事情,努力,加油,坚持……linkstudio-xiang
xiang588.cublog.cn


JPA 批注2

@Column

默认情况下,JPA 持续性提供程序假设每个实体的持久字段存储在其名称与持久字段的名称相匹配的数据库表列中。

使用 @Column 批注:

  • 将持久字段与其他名称关联(如果默认列名难于处理、与事先存在的数据模型不兼容或作为数据库中的列名无效)

  • 将持久字段与辅助表中的列关联(请参阅 @SecondaryTable

  • 微调数据库中列的特征

表 1-7 列出了此批注的属性。有关更多详细信息,请参阅 API

表 1-7 @Column 属性

属性 必需 说明

columnDefinition

可选


默认值:空 String

默认情况下,JPA 使用最少量 SQL 创建一个数据库表列。

如果需要使用更多指定选项创建的列,请将 columnDefinition 设置为在针对列生成 DDL 时希望 JPA 使用的 SQL 片断。

注意:捕获批注中的 DDL 信息时,某些 JPA 持续性提供程序可以在生成数据库模式时使用此 DDL。例如,请参阅“用于 Java2DB 模式生成的 TopLink JPA 扩展”

insertable

可选


默认值true

默认情况下,JPA 持续性提供程序假设所有列始终包含在 SQL INSERT 语句中。

如果该列不应包含在这些语句中,请将 insertable 设置为 false

length

可选


默认值: 255

默认情况下,JPA 持续性提供程序假设所有列在用于保存 String 值时的最大长度为 255 个字符。

如果该列不适合于您的应用程序或数据库,请将 length 设置为适合于您的数据库列的 int 值。

name

可选


默认值:JPA 持续性提供程序假设实体的每个持久字段都存储在其名称与持久字段或属性的名称相匹配的数据库表列中。

要指定其他列名,请将 name 设置为所需的 String 列名。

nullable

可选


默认值true

默认情况下,JPA 持续性提供程序假设允许所有列包含空值。

如果不允许该列包含空值,请将 nullable 设置为 false

precision

可选


默认值: 0.

默认情况下,JPA 持续性提供程序假设所有列在用于保存十进制(精确数字)值时的精度为 0。

如果该精度不适合于您的应用程序或数据库,请将 precision 设置为相应的 int 精度。

scale

可选


默认值: 0.

默认情况下,JPA 持续性提供程序假设所有列在用于保存十进制(精确数字)值时的伸缩度为 0。

如果该伸缩度不适合于您的应用程序或数据库,请将 scale 设置为相应的 int 精度。

table

可选


默认值:JPA 持续性提供程序假设实体的所有持久字段都存储到一个其名称为实体名称的数据库表中(请参阅 @Table)。

如果该列与辅助表关联(请参阅 @SecondaryTable),请将 name 设置为相应辅助表名称的 String 名称,如示例 1-8 所示。

unique

可选


默认值false

默认情况下,JPA 持续性提供程序假设允许所有列包含重复值。

如果不允许该列包含重复值,请将 unique 设置为 true。设置为 true 时,这相当于在表级别使用 @UniqueConstraint

updatable

可选


默认值true

默认情况下,JPA 持续性提供程序假设列始终包含在 SQL UPDATE 语句中。

如果该列不应包含在这些语句中,请将 updatable 设置为 false


示例 1-8 显示了如何使用此批注使 JPA 将 empId 持久保存到辅助表 EMP_HR 中的列 EMP_NUM。默认情况下,JPA 将 empName 持久保存到主表 Employee 中的列 empName

示例 1-8 @Column

@Entity
@SecondaryTable(name="EMP_HR")
public class Employee implements Serializable {
    ...
@Column(name="EMP_NUM", table="EMP_HR")
private Long empId;

private String empName;
    ...
}

@ColumnResult

执行 @NamedNativeQuery 时,它可以返回实体(包括不同类型的实体)、标量值或实体和标量值的组合。

使用 @ColumnResult 批注返回标量值。标量类型由您在 @ColumnResult 中标识的列类型确定。

有关详细信息,另请参阅 @EntityResult@FieldResult@SqlResultSetMapping

表 1-8 列出了此批注的属性。有关更多详细信息,请参阅 API

表 1-8 @ColumnResult 属性

属性 必需 说明

name

必需


在原生 SQL 查询的 SELECT 语句中将 name 设置为列名的 String 等效形式。如果在 SELECT 中使用列别名(AS 语句),则将 name 设置为列别名。


示例 1-9 显示了如何使用此批注将 Item(请参阅示例 1-10)标量 name 包含在结果列表(请参阅示例 1-11)中。在该示例中,结果列表将为 Object 数组的 List,如:{[Order, "Shoes"], [Order, "Socks"], ...}

示例 1-9 使用 @ColumnResult 的 Order 实体

@SqlResultSetMapping(
name="OrderResults",
entities={
@EntityResult(
entityClass=Order.class, 
fields={
@FieldResult(name="id",       column="order_id"),
@FieldResult(name="quantity", column="order_quantity"),
@FieldResult(name="item",     column="order_item")
            }
        )
    },
columns={
@ColumnResult(
name="item_name"
        )
    }
)
@Entity
public class Order {
@Id
protected int id;
protected long quantity;
protected Item item;
    ...
}

示例 1-10 Item 实体

@Entity
public class Item {
@Id
protected int id;
protected String name;
    ...
}

示例 1-11 结合使用 @SqlResultSetMapping 与 @ColumnResult 的原生查询

Query q = entityManager.createNativeQuery(
"SELECT o.id       AS order_id, " +
"o.quantity AS order_quantity, " +
"o.item     AS order_item, " + 
"i.name     AS item_name, " +
"FROM Order o, Item i " +
"WHERE (order_quantity > 25) AND (order_item = i.id)",
"OrderResults"
);

List resultList = q.getResultList(); 
// List of Object arrays:{[Order, "Shoes"], [Order, "Socks"], ...}

@DiscriminatorColumn

默认情况下,当 @Inheritance 属性策略为 InheritanceType.SINGLE_TABLEJOINED 时,JPA 持续性提供程序将创建一个名为 DTYPE 的标识符列以区分继承层次中的类。

使用 @DiscriminatorColumn 批注:

  • 指定一个标识符列名(如果数据模型中的列名不是默认列名 DTYPE)。

  • 指定一个适用于应用程序或事先存在的数据模型的标识符列长度

  • 微调数据库中的标识符列的特征

表 1-9 列出了此批注的属性。有关更多详细信息,请参阅 API

表 1-9 @DiscriminatorColumn 属性

属性 必需 说明

columnDefinition

可选


默认值:空 String

默认情况下,JPA 持续性提供程序使用最少量 SQL 创建一个数据库表列。

如果需要使用更多指定选项创建的列,请将 columnDefinition 设置为在针对列生成 DDL 时希望 JPA 使用的 SQL 片断。

discriminatorType

可选


默认值DiscriminatorType.STRING

默认情况下,JPA 持续性提供程序假设标识符类型为 String

如果要使用其他类型,请将 discriminatorType 设置为 DiscriminatorType.CHARDiscriminatorType.INTEGER

您的 @DiscriminatorValue 必须符合此类型。

length

可选


默认值: 31

默认情况下,JPA 持续性提供程序假设标识符列在用于保存 String 值时的最大长度为 255 个字符。

如果该列不适合于您的应用程序或数据库,请将 length 设置为适合于您的数据库列的 int 值。

您的 @DiscriminatorValue 必须符合此长度。

name

可选


默认值:JPA 持续性提供程序假设标识符列名为“DTYPE”。

要指定其他列名,请将 name 设置为所需的 String 列名。


示例 1-12 显示了如何使用此批注指定一个名为 DISC、类型为 STRING、长度为 20 的标识符列。在本示例中,该类的 @DiscriminatorValue 指定为 CUST示例 1-13 中的子类将它自己的 @DiscriminatorValue 指定为 VIP。在 CustomerValuedCustomer 中,@DiscriminatorValue 的值必须可以转换为由 @DiscriminatorColumn 属性 discriminatorType 指定的类型,并且必须符合 @DiscriminatorColumn 属性 length

示例 1-12 @DiscriminatorColumn 和 @DiscriminatorValue — 根类

@Entity
@Table(name="CUST")
@Inheritance(strategy=SINGLE_TABLE)
@DiscriminatorColumn(name="DISC", discriminatorType=STRING, length=20)
@DiscriminatorValue(value-"CUST")
public class Customer {
    ... 
}

示例 1-13 @DiscriminatorValue — 子类

@Entity
@DiscriminatorValue(value="VIP")
public class ValuedCustomer extends Customer { 
    ... 
}

@DiscriminatorValue

默认情况下,当 @Inheritance 属性策略为 InheritanceType.SINGLE_TABLEJOINED 时,JPA 持续性提供程序使用 @DiscriminatorColumn 按实体名称区分继承层次中的类(请参阅 @Entity)。

使用 @DiscriminatorValue 批注指定用于区分此继承层次中的实体的标识符值:

  • 如果实体名称不适合于此应用程序

  • 匹配现有的数据库模式

表 1-10 列出了此批注的属性。有关更多详细信息,请参阅 API

表 1-10 @DiscriminatorValue 属性

属性 必需 说明

value

必需


value 设置为符合 @DiscriminatorColumn 属性 discriminatorTypelength 的标识符值的 String 等效形式。


示例 1-14 显示了如何使用此批注指定一个名为 DISC、类型为 STRING、长度为 20 的标识符列。在本示例中,该类的 @DiscriminatorValue 指定为 CUST示例 1-15 中的子类将它自己的 @DiscriminatorValue 指定为 VIP。在 CustomerValuedCustomer 中,@DiscriminatorValue 的值必须可以转换为由 @DiscriminatorColumn 属性 discriminatorType 指定的类型,并且必须符合 @DiscriminatorColumn 属性 length

示例 1-14 @DiscriminatorColumn 和 @DiscriminatorValue — 根类

@Entity
@Table(name="CUST")
@Inheritance(strategy=SINGLE_TABLE)
@DiscriminatorColumn(name="DISC", discriminatorType=STRING, length=20)
@DiscriminatorValue(value-"CUST")
public class Customer {
    ... 
}

示例 1-15 @DiscriminatorValue — 子类

@Entity
@DiscriminatorValue(value="VIP")
public class ValuedCustomer extends Customer { 
    ... 
}

@Embeddable

默认情况下,JPA 持续性提供程序假设每个实体均持久保存到它自己的数据库表。

使用 @Embeddable 批注指定一个类,该类的实例存储为拥有实体的固有部分并共享该实体的身份。嵌入对象的每个持久属性或字段都将映射到实体的数据库表。

此批注没有属性。有关更多详细信息,请参阅 API

示例 1-16 显示了如何使用此批注指定:类 EmploymentPeriod 在用作批注为 @Embedded 的持久字段的类型时可以嵌套到实体中(请参阅示例 1-17

示例 1-16 @Embeddable

@Embeddable
public class EmploymentPeriod {
java.util.Date startDate;
java.util.Date endDate;
    ...
}

@Embedded

默认情况下,JPA 持续性提供程序假设每个实体均持久保存到它自己的数据库表。

使用 @Embedded 批注指定一个持久字段,该字段的 @Embeddable 类型可以存储为拥有实体的固有部分,并共享该实体的身份。嵌入对象的每个持久属性或字段均映射到拥有实体的数据库表。

可以结合使用 @Embedded@Embeddable 以建立严格所有权关系的模型,以便在删除了拥有对象的情况下还将删除被拥有的对象。

嵌入的对象不应映射到多个表。

默认情况下,@Embeddable 类中指定的列定义(请参阅 @Column)适用于 @Embedded 类。如果要覆盖这些列定义,请使用 @AttributeOverride

此批注没有属性。有关更多详细信息,请参阅 API

示例 1-17 显示了如何使用该批注指定:@EmbeddableEmploymentPeriod(请参阅示例 1-16)可以使用指定的属性覆盖(请参阅 @AttributeOverride)嵌入到实体类中。如果不需要属性覆盖,则可以完全忽略 @Embedded 批注:JPA 持续性提供程序将推断出 EmploymentPeriod 是从它的 @Embeddable 批注进行嵌套。

示例 1-17 @Embedded

@Entity
public class Employee implements Serializable {
    ...
@Embedded
@AttributeOverrides({
@AttributeOverride(name="startDate", column=@Column("EMP_START")),
@AttributeOverride(name="endDate", column=@Column("EMP_END"))
    )
public EmploymentPeriod getEmploymentPeriod() { 
        ... 
    }
    ...
}

@EmbeddedId

使用 @EmbeddedId 批注指定一个由实体拥有的可嵌入复合主键类(通常由两个或更多基元类型或 JDK 对象类型组成)。从原有数据库映射时(此时数据库键由多列组成),通常将出现复合主键。

复合主键类具有下列特征:

  • 它是一个普通的旧式 Java 对象 (POJO) 类。

  • 它必须为 public,并且必须有一个 public 无参数构造函数。

  • 如果使用基于属性的访问,则主键类的属性必须为 public 或 protected。

  • 它必须是可序列化的。

  • 它必须定义 equalshashCode 方法。

    这些方法的值相等性的语义必须与键映射到的数据库类型的数据库相等性一致。

或者,您可以使复合主键类成为非嵌入类(请参阅 @IdClass)。

此批注没有属性。有关更多详细信息,请参阅 API

示例 1-18 显示了一个批注为 @Embeddable 的典型复合主键类。示例1-19 显示了如何使用可嵌入的复合主键类(使用 @EmbeddedId 批注)配置一个实体。

示例 1-18 可嵌入复合主键类

@Embeddable
public class EmployeePK implements Serializable
{
private String name;
private long id;

public EmployeePK()
    {
    }

public String getName()
    {
return name;
    }

public void setName(String name)
    {
this.name = name;
    }

public long getId()
    {
return id;
    }

public void setId(long id)
    {
this.id = id;
    }

public int hashCode()
    {
return (int) name.hashCode() + id;
    }

public boolean equals(Object obj)
    {
if (obj == this) return true;
if (!(obj instanceof EmployeePK)) return false;
if (obj == null) return false;
EmployeePK pk = (EmployeePK) obj;
return pk.id == id && pk.name.equals(name);
    }
}

示例 1-19 @EmbeddedId

@Entity
public class Employee implements Serializable
{
EmployeePK primaryKey;
 
public Employee()
    {
    }
 
@EmbeddedId
public EmployeePK getPrimaryKey()
    {
return primaryKey;
    }
 
public void setPrimaryKey(EmployeePK pk)
    {
primaryKey = pk;
    }
 
    ...
}

@Entity

使用 @Entity 批注将普通的旧式 Java 对象 (POJO) 类指定为实体,并使其可用于 JPA 服务。必须将 POJO 类指定为实体,然后才可以使用任何其他 JPA 批注。

表 1-11 列出了此批注的属性。有关更多详细信息,请参阅 API

表 1-11 @Entity 属性

属性 必需 说明

name

可选


默认值:JPA 持续性提供程序假设实体名称是实体类的名称。在示例 1-20 中,默认 name 为“Employee”。

如果实体类名难于处理、是一个保留字、与事先存在的数据模型不兼容或作为数据库中的表名无效,请将 name 设置为其他 String 值。


示例 1-20 显示了该批注的用法。

示例 1-20 @Entity

@Entity
public class Employee implements Serializable {
    ...
}

@EntityListeners

可以使用生命周期批注(请参阅生命周期事件批注)指定实体中的方法,这些方法在指定的生命周期事件发生时执行您的逻辑。

使用 @EntityListeners 批注将一个或多个实体监听程序类与 @Entity@MappedSuperclass 关联,条件是您需要在指定的生命周期事件发生时执行逻辑,以及:

  • 不希望在实体 API 中公开生命周期监听程序方法。

  • 要在不同的实体类型之间共享生命周期监听程序逻辑。

当实体或子类上发生生命周期事件时,JPA 持续性提供程序将按监听程序定义的顺序通知每个实体监听程序,并调用使用相应的生命周期事件类型进行批注的实体监听程序方法(如果有)。

实体监听程序类具有以下特征:

  • 它是一个普通的旧式 Java 对象 (POJO) 类

  • 它有一个或多个具有以下签名的回调方法:

    public void <MethodName>(Object)
    
    

    可以指定参数类型 Object,或实体监听程序将与其关联的实体类的类型。

  • 它用一个或多个生命周期事件批注对每个回调方法进行批注。

    一个生命周期事件只能与一个回调监听程序方法关联,但某个给定的回调监听程序方法可以与多个生命周期事件关联。

如果使用实体监听程序,则可以管理哪些实体监听程序使用 @ExcludeDefaultListeners@ExcludeSuperclassListeners 调用。

表 1-12 列出了此批注的属性。有关更多详细信息,请参阅 API

表 1-12 @EntityListeners 属性

属性 必需 说明

value

必需


要为 @Entity@MappedSuperclass 指定实体监听程序类的列表,请将 value 设置为实体监听程序类的 Class 数组。


示例 1-21 显示了如何使用此批注将实体监听程序类 EmployeePersistListener(请参阅示例 1-22)和 EmployeeRemoveListener(请参阅示例 1-23)与实体 Employee 关联。示例 1-23 显示了您可以将多个生命周期事件与给定的实体监听程序类方法关联,但任何给定的生命周期事件只能在实体监听程序类中出现一次。

示例 1-21 @EntityListeners

@Entity
@EntityListeners(value={EmployeePersistListner.class, EmployeeRemoveListener.class})
public class Employee implements Serializable {
    ...
}

示例 1-22 EmployeePersistListener

public class EmployeePersistListener {
@PrePersist
employeePrePersist(Object employee) {
    ...
    }
    ...
}

示例 1-23 EmployeeRemoveListener

public class EmployeeRemoveListener {
@PreRemove
@PostRemove
employeePreRemove(Object employee) {
    ...
    }
    ...
}

@EntityResult

执行 @NamedNativeQuery 时,它可以返回实体(包括不同类型的实体)、标量值或实体和标量值的组合。

使用 @EntityResult 批注返回实体。

有关详细信息,另请参阅 @ColumnResult@FieldResult@SqlResultSetMapping

表 1-8 列出了此批注的属性。有关更多详细信息,请参阅 API

表 1-13 @EntityResult 属性

属性 必需 说明

entityClass

必需


entityClass 设置为由 SELECT 语句返回的实体的 Class

discriminatorColumn

可选


默认值:空 String

默认情况下,JPA 持续性提供程序假设 SELECT 语句中不包含标识符列(请参阅 @Inheritance)。

如果在 SELECT 语句中使用标识符列,请将 discriminatorColumn 设置为所使用的 String 列名。

fields

可选


默认值:空 FieldResult 数组。

默认情况下,JPA 持续性提供程序假设 SELECT 语句包含与返回的实体的所有字段或属性相对应的所有列,且 SELECT 语句中的列名对应于字段或属性名(未使用 AS 语句)。

如果 SELECT 语句只包含某些与返回的实体的字段或属性相对应的列,或 SELECT 语句中的列名并不对应于字段或属性名(使用了 AS 语句),请将 fields 设置为 @FieldResult 的数组,SELECT 语句中的每一列一个 @FieldResult


示例 1-24 显示了如何使用此批注将 OrderItem(请参阅示例 1-25)实体包含在结果列表(请参阅示例 1-26)中。在该示例中,结果列表将为 Object 数组的 List,如:{[Order, Item], [Order, Item], ...}

示例 1-24 使用 @EntityResult 的 Order 实体

@SqlResultSetMapping(
name="OrderResults",
entities={
@EntityResult(
entityClass=Order.class, 
fields={
@FieldResult(name="id",       column="order_id"),
@FieldResult(name="quantity", column="order_quantity"),
@FieldResult(name="item",     column="order_item")
            }
        ),
@EntityResult(
entityClass=Item.class,
fields={
@FieldResult(name="id",       column="item_id"),
@FieldResult(name="name",     column="item_name"),
            }
        )
    }
)
@Entity
public class Order {
@Id
protected int id;
protected long quantity;
protected Item item;
    ...
}

示例 1-25 Item 实体

@Entity
public class Item {
@Id
protected int id;
protected String name;
    ...
}

示例 1-26 结合使用 @SqlResultSetMapping 与 @EntityResult 的原生查询

Query q = entityManager.createNativeQuery(
"SELECT o.id       AS order_id, " +
"o.quantity AS order_quantity, " +
"o.item     AS order_item, " + 
"i.id       AS item_id, " +
"i.name     AS item_name, " +
"FROM Order o, Item i " +
"WHERE (order_quantity > 25) AND (order_item = i.id)",
"OrderResults"
);

List resultList = q.getResultList(); 
// List of Object arrays:{[Order, Item], [Order, Item], ...}

@Enumerated

默认情况下,JPA 持续性提供程序持久保存枚举常量的序数值。

使用 @Enumerated 批注指定在 String 值适合应用程序要求或与现有数据库模式匹配的情况下,JPA 持续性提供程序是否应持久保存枚举常量的序数值或 String 值。

该批注可以与 @Basic 一起使用。

表 1-14 列出了此批注的属性。有关更多详细信息,请参阅 API

表 1-14 @Enumerated 属性

属性 必需 说明

value

可选


默认值EnumType.ORDINAL

默认情况下,JPA 持续性提供程序假设对于映射到枚举常量的属性或字段,应持久保存序数值。在示例 1-28 中,当持久保存 Employee 时,EmployeeStatus 的序数值将写入数据库。

如果需要持久保存的枚举常量的 String 值,请将 value 设置为 EnumType.STRING


根据示例 1-27 中的枚举常量,示例 1-28 显示了如何使用此批注指定在持久保存 Employee 时应将 SalaryRateString 值写入数据库。默认情况下,会将 EmployeeStatus 的序数值写入数据库。

示例 1-27 枚举常量

public enum EmployeeStatus {FULL_TIME, PART_TIME, CONTRACT}
public enum SalaryRate {JUNIOR, SENIOR, MANAGER, EXECUTIVE}

示例 1-28 @Enumerated

@Entity
public class Employee {
    ...
public EmployeeStatus getStatus() {
    ...
    }

@Enumerated(STRING)
public SalaryRate getPayScale() {
    ...
    }
    ...
}

@ExcludeDefaultListeners

默认监听程序是 orm.xml 文件中指定的一个生命周期事件监听程序类,该类应用于持续性单元(请参阅 @PersistenceUnit)中的所有实体。在调用任何其他实体监听程序(请参阅 @EntityListeners)之前,JPA 持续性提供程序首先按照 orm.xml 文件中定义的顺序调用默认监听程序(如果有)。

如果默认监听程序行为不适用,请使用 @ExcludeDefaultListeners 批注覆盖(并阻止)针对给定 @Entity@MappedSuperclass 执行的默认监听程序。

此批注没有属性。有关更多详细信息,请参阅 API

示例 1-29 显示了如何使用此批注指定不应对 Employee 实体执行默认监听程序。

示例 1-29 @ExcludeDefaultListeners

@Entity
@ExcludeDefaultListeners
public class Employee implements Serializable {
    ...
}

@ExcludeSuperclassListeners

如果继承层次中的 @Entity@MappedSuperclass 类定义了 @EntityListeners,则默认情况下,JPA 持续性提供程序将在调用子类监听程序之前调用超类监听程序。

如果超类监听程序行为不适用,则使用 @ExcludeSuperclassListeners 批注覆盖(并阻止)针对给定 @Entity@MappedSuperclass 执行的超类监听程序。

@ExcludeSuperclassListeners 批注不影响默认监听程序(请参阅 @ExcludeDefaultListeners)。

此批注没有属性。有关更多详细信息,请参阅 API

示例 1-29 显示了如何使用此批注指定不应对 PartTimeEmployee 实体执行超类监听程序 EmployeeListener,而是执行默认监听程序和子类监听程序 PartTimeEmployeeListener1PartTimeEmployeeListener2

示例 1-30 超类级别的实体监听程序

@MappedSuperclass
@EntityListeners(value={EmployeeListener.class})
public class Employee {
    ... 
}

示例 1-31 子类级别的 @ExcludeSuperclassListeners

@Entity
@ExcludeSuperclassListeners
@EntityListners(value={PartTimeEmployeeListener1.class, PartTimeEmployeeListener2.class})
public class PartTimeEmployee extends Employee {
    ...
}

@FieldResult

执行 @NamedNativeQuery 时,它可以返回实体(包括不同类型的实体)、标量值或实体和标量值的组合。

默认情况下,JPA 持续性提供程序假设在使用 @EntityResult 返回实体时,SELECT 语句将包含与返回的实体的所有字段或属性相对应的所有列,且 SELECT 语句中的列名对应于字段或属性名(未使用 AS 语句)。

如果 SELECT 语句只包含某些与返回的实体的字段或属性相对应的列,或 SELECT 语句中的列名并不对应于字段或属性名(使用了 AS 语句),则在使用 @EntityResult 返回实体时,请使用 @FieldResult 批注将 SELECT 语句中的列映射到字段或属性。

有关详细信息,另请参阅 @ColumnResult@SqlResultSetMapping

表 1-15 列出了此批注的属性。有关更多详细信息,请参阅 API

表 1-15 @FieldResult 属性

属性 必需 说明

column

必需


column 设置为 SELECT 语句中使用的列的 String 名称。如果在 SELECT 中使用列别名(AS 语句),请将 column 设置为列别名。

name

必需


name 设置为实体的字段或属性名(作为 String),该名称对应于 column 属性指定的列名。


示例 1-32 显示了如何使用此批注将 OrderItem(请参阅示例 1-33)实体包含在结果列表(请参阅示例 1-34)中。在该示例中,结果列表将为 Object 数组的 List,如:{[Order, Item], [Order, Item], ...}

示例 1-32 使用 @EntityResult 和 @FieldResult 的 Order 实体

@SqlResultSetMapping(
name="OrderResults",
entities={
@EntityResult(
entityClass=Order.class, 
fields={
@FieldResult(name="id",       column="order_id"),
@FieldResult(name="quantity", column="order_quantity"),
@FieldResult(name="item",     column="order_item")
            }
        ),
@EntityResult(
entityClass=Item.class,
fields={
@FieldResult(name="id",       column="item_id"),
@FieldResult(name="name",     column="item_name"),
            }
        )
    }
)
@Entity
public class Order {
@Id
protected int id;
protected long quantity;
protected Item item;
    ...
}

示例 1-33 Item 实体

@Entity
public class Item {
@Id
protected int id;
protected String name;
    ...
}

示例 1-34 结合使用 @SqlResultSetMapping 与 @EntityResult 的原生查询

Query q = entityManager.createNativeQuery(
"SELECT o.id       AS order_id, " +
"o.quantity AS order_quantity, " +
"o.item     AS order_item, " + 
"i.id       AS item_id, " +
"i.name     AS item_name, " +
"FROM Order o, Item i " +
"WHERE (order_quantity > 25) AND (order_item = i.id)",
"OrderResults"
);

List resultList = q.getResultList(); 
// List of Object arrays:{[Order, Item], [Order, Item], ...}

@GeneratedValue

默认情况下,JPA 持续性提供程序管理为实体主键提供的唯一标识符(请参阅 @Id)。

如果要微调此机制以实现以下目的,请使用 @GeneratedValue 批注:

  • 如果您感觉另一个生成器类型更适合于数据库或应用,则覆盖持续性提供程序为数据库选择的身份值生成的类型

  • 如果此名称难于处理、是一个保留字、与事先存在的数据模型不兼容或作为数据库中的主键生成器名称无效,则覆盖持续性提供程序选择的主键生成器名称

表 1-16 列出了此批注的属性。有关更多详细信息,请参阅 API

表 1-16 @GeneratedValue 属性

属性 必需 说明

generator

可选


默认值:JPA 持续性提供程序为它选择的主键生成器分配一个名称。

如果该名称难于处理、是一个保留字、与事先存在的数据模型不兼容或作为数据库中的主键生成器名称无效,则将 generator 设置为要使用的 String 生成器名称。

strategy

可选


默认值GenerationType.AUTO

默认情况下,JPA 持续性提供程序选择最适合于基础数据库的主键生成器类型。

如果您感觉另一个生成器类型更适合于数据库或应用程序,请将 strategy 设置为所需的 GeneratorType

  • IDENTITY — 指定持续性提供程序使用数据库身份列

  • AUTO — 指定持续性提供程序应选择一个最适合于基础数据库的主键生成器。

  • SEQUENCE — 指定持续性提供程序使用数据库序列(请参阅 @SequenceGenerator

  • TABLE — 指定持续性提供程序为使用基础数据库表的实体分配主键以确保唯一性(请参阅 @TableGenerator


示例 1-35 显示了如何使用此批注指示持续性提供程序使用名为 CUST_SEQ、类型为 GeneratorType.SEQUENCE 的主键生成器。

示例 1-35 @GeneratedValue

@Entity
public class Employee implements Serializable {
    ...
@Id
@GeneratedValue(strategy=SEQUENCE, generator="CUST_SEQ")
@Column(name="CUST_ID")
public Long getId() { 
return id; 
    }
    ...
}

@Id

使用 @Id 批注将一个或多个持久字段或属性指定为实体的主键。

对于每个实体,必须至少指定以下项之一:

此批注没有属性。有关更多详细信息,请参阅 API

默认情况下,JPA 持续性提供程序选择最合适的主键生成器(请参阅 @GeneratedValue)并负责管理主键值:您不必采取任何进一步的操作。如果要使用 JPA 持续性提供程序的默认键生成机制,则不必采取任何进一步的操作。

示例 1-36 显示了如何使用此批注将持久字段 empID 指定为 Employee 表的主键。

示例 1-36 @Id

@Entity
public class Employee implements Serializable {
@Id
private int empID;
    ...
}

@IdClass

使用 @IdClass 批注为实体指定一个复合主键类(通常由两个或更多基元类型或 JDK 对象类型组成)。从原有数据库映射时(此时数据库键由多列组成),通常将出现复合主键。

复合主键类具有下列特征:

  • 它是一个普通的旧式 Java 对象 (POJO) 类。

  • 它必须为 public,并且必须有一个 public 无参数构造函数。

  • 如果使用基于属性的访问,则主键类的属性必须为 public 或 protected。

  • 它必须是可序列化的。

  • 它必须定义 equalshashCode 方法。

    这些方法的值相等性的语义必须与键映射到的数据库类型的数据库相等性一致。

  • 它的字段或属性的类型和名称必须与使用 @Id 进行批注的实体主键字段或属性的类型和名称相对应。

或者,您可以使复合主键类成为由实体拥有的嵌入类(请参阅 @EmbeddedId)。

表 1-17 列出了此批注的属性。有关更多详细信息,请参阅 API

表 1-17 @IdClass 属性

属性 必需 说明

value

必需


要指定复合主键类,请将 value 设置为所需的 Class(请参阅 @AttributeOverride)。


示例 1-37 显示了一个非嵌入的复合主键类。在该类中,字段 empNamebirthDay 的名称和类型必须对应于实体类中属性的名称和类型。示例 1-38 显示了如何使用这个非嵌入的复合主键类(使用 @IdClass 批注)配置 EJB 3.0 实体。由于实体类字段 empNamebirthDay 在主键中使用,因此还必须使用 @Id 批注对其进行批注。

示例 1-37 非嵌入的复合主键类

public class EmployeePK implements Serializable
{
private String empName;
private Date birthDay;

public EmployeePK()
    {
    }

public String getName()
    {
return empName;
    }

public void setName(String name)
    {
empName = name;
    }

public long getDateOfBirth()
    {
return birthDay;
    }

public void setDateOfBirth(Date date)
    {
birthDay = date;
    }

public int hashCode()
    {
return (int) empName.hashCode();
    }

public boolean equals(Object obj)
    {
if (obj == this) return true;
if (!(obj instanceof EmployeePK)) return false;
if (obj == null) return false;
EmployeePK pk = (EmployeePK) obj;
return pk.birthDay == birthDay && pk.empName.equals(empName);
    }
}

示例 1-38 @IdClass

@IdClass(EmployeePK.class)
@Entity
public class Employee
{
@Id String empName;
@Id Date birthDay;
...
}

@Inheritance

默认情况下,JPA 持续性提供程序自动管理继承层次中实体的持续性。

使用 @Inheritance 批注自定义持续性提供程序的继承层次支持,以提高应用程序性能或匹配现有的数据模型。

表 1-18 列出了此批注的属性。有关更多详细信息,请参阅 API

表 1-18 @Inheritance 属性

属性 必需 说明

strategy

可选


默认值InheritanceType.SINGLE_TABLE

默认情况下,JPA 持续性提供程序假设层次中的所有类均映射到一个由表的标识符列(请参阅 @DiscriminatorColumn)中的标识符值(请参阅 @DiscriminatorValue)区分的表。

如果这并不适合于应用程序,或者如果必须匹配现有的数据模型,请将 strategy 设置为所需的 InheritanceType

  • SINGLE_TABLEFoot?1? — 层次中的所有类均映射到一个表。该表有一个标识符列(请参阅 @DiscriminatorColumn),它的值(请参阅 @DiscriminatorValue)标识由行表示的实例所属的特定子类。

  • TABLE_PER_CLASS — 每个类均映射到单独的表。该类的所有属性(包括继承的属性)映射到该类的表列。

  • JOINED — 类层次的根由一个表表示,而每个子类由单独的表表示。每个子类表只包含特定于该子类的那些字段(而非从其超类继承的字段)和主键列,这些主键列用作超类表主键的外键。


Footnote?1?该选项为跨类层次的实体和查询之间的多态关系提供了最佳支持。该选项的缺点包括需要生成应为 NOT NULL 的可空列。

示例 1-39 显示了如何使用此批注指定 Customer 的所有子类将使用 InheritanceType.JOINED示例 1-40 中的子类将映射到它自己的表(该表针对 ValuedCustomer 的每个持久属性包含一列)和一个外键列(包含 Customer 表的主键)。

示例 1-39 @Inheritance — 使用 JOINED 的根类

@Entity@Inheritance(strategy=JOINED)public class Customer { 
@Id
private int customerId;
    ... 
}

示例 1-40 @Inheritance — 使用 JOINED 的子类

@Entity
public class ValuedCustomer extends Customer { 
    ... 
}

示例 1-41 中,默认情况下,InheritanceType.SINGLE_TABLE 应用于 Customer 及其所有子类。在该示例中,默认标识符表列 DTYPE(请参阅 @DiscriminatorColumn)指定为具有标识符类型 INTEGER,且 Customer@DiscriminatorValue 指定为 1示例 1-42 显示了如何将子类 ValuedCustomer 的标识符值指定为 2。在该示例中,CustomerValuedCustomer 的所有持久属性将映射到一个表。

示例 1-41 @Inheritance — 指定其标识符列的根类

@Entity
@DiscriminatorColumn(discriminatorType=DiscriminatorType.INTEGER)
@DiscriminatorValue(value="1")
public class Customer { 
    ... 
}

示例 1-42 @Inheritance — 指定其标识符值的子类

@Entity
@DiscriminatorValue(value="2")
public class ValuedCustomer extends Customer { 
    ... 
}

发表于: 2008-04-28 ,修改于: 2008-04-28 09:32,已浏览208次,有评论0条 推荐 投诉


网友评论

发表评论