JPA 批注3

xiaoxiao2022-06-12  80

@JoinColumn

默认情况下,在实体关联中,JPA 持续性提供程序使用一个基于现有名称(如字段或属性名称)的数据库模式,以便它可以自动确定要使用的单个连接列(包含外键的列)。

在以下条件下使用 @JoinColumn 批注:

默认连接列名称难于处理、是一个保留字、与预先存在的数据模型不兼容或作为数据库中的列名无效

您需要使用外部表中的列(非主键列)进行连接

您想要使用两个或更多连接列(请参阅 @JoinColumns

您想要使用一个连接表(请参阅 @JoinTable

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

表 1-19 @JoinColumn 属性

属性必需说明

columnDefinition

默认值:空 String。

JPA 使用最少量 SQL 创建一个数据库表列。

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

insertable

默认值:true。

默认情况下,JPA 持续性提供程序假设它可以插入到所有表列中。

如果该列为只读,请将 insertable 设置为 false。

name

默认值:如果使用一个连接列,则 JPA 持续性提供程序假设外键列的名称是以下名称的连接:

引用关系属性的名称 +“_”+ 被引用的主键列的名称。

引用实体的字段名称 +“_”+ 被引用的主键列的名称。

如果实体中没有这样的引用关系属性或字段(请参阅 @JoinTable),则连接列名称格式化为以下名称的连接:实体名称 +“_”+ 被引用的主键列的名称。

这是外键列的名称。如果连接针对“一对一”或“多对一”实体关系,则该列位于源实体的表中。如果连接针对“多对多”实体关系,则该列位于连接表(请参阅 @JoinTable)中。

如果连接列名难于处理、是一个保留字、与预先存在的数据模型不兼容或作为数据库中的列名无效,请将 name 设置为所需的 String 列名。

nullable

默认值:true。

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

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

referencedColumnName

默认值:如果使用一个连接列,则 JPA 持续性提供程序假设在实体关系中,被引用的列名是被引用的主键列的名称。

如果在连接表(请参阅 @JoinTable)中使用,则被引用的键列位于拥有实体(如果连接是反向连接定义的一部分,则为反向实体)的实体表中。

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

table

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

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

unique

默认值:false。

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

如果不允许该列包含重复值,请将 unique 设置为 true。

updatable

默认值:true。

默认情况下,JPA 持续性提供程序假设它可以更新所有表列。

如果该列为只读,则将 updatable 设置为 false

示例 1-43 显示了如何使用此批注使 JPA 将数据库表 Employee 列 ADDR_ID 用作连接列。示例 1-43 @JoinColumn @Entitypublic class Employee implements Serializable { ...@ManyToOne@JoinColumns({@JoinColumn(name="ADDR_ID", referencedColumnName="ID"),@JoinColumn(name="ADDR_ZIP", referencedColumnName="ZIP") })public Address getAddress() {return address; } ...}

@JoinTable

默认情况下,JPA 持续性提供程序在映射多对多关联(或在单向的一对多关联中)的拥有方上的实体关联时使用一个连接表。连接表名称及其列名均在默认情况下指定,且 JPA 持续性提供程序假设:在关系的拥有方上的实体主表中,每个主键列有一个连接列。

如果您需要执行以下操作,请使用 @JoinTable 批注:

由于默认名称难于处理、是一个保留字、与预先存在的数据模型不兼容或作为数据库中的表名无效而更改连接表的名称

由于默认名称难于处理、是一个保留字、与预先存在的数据模型不兼容或作为数据库中的列名无效而更改连接表的列名称

使用特定目录或模式配置连接表

使用唯一约束配置一个或多个连接表列

每个实体使用多个连接列

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

表 1-21 @JoinTable 属性

属性必需说明

catalog

默认值:空 String。

默认情况下,JPA 使用任何适用于数据库的默认目录。

如果默认目录不适合于应用程序,请将 catalog 设置为要使用的 String 目录名。

inverseJoinColumns

默认值:JoinColumn 的空数组。

默认情况下,JPA 持续性提供程序假设关联的被拥有方(或另一方)上有一个连接列:被拥有实体的主键列。JPA 通过连接被拥有实体的名称 +“_”+ 被引用的主键列的名称来命名该列。

如果这样的列名难于处理、是一个保留字、与预先存在的数据模型不兼容,或者如果要指定多个连接列,则将 joinColumns 设置为 JoinColumn(请参阅 @JoinColumn)的一个或多个实例。

joinColumns

默认值:JoinColumn 的空数组。

默认情况下,JPA 持续性提供程序假设:拥有实体的每个主键列都有一个连接列。该持续性提供程序通过连接拥有实体的名称+“_”+ 被引用主键列的名称来命名这些列。

如果这样的列名难于处理、是一个保留字、与预先存在的数据模型不兼容,或者如果要指定多个连接列,则将 joinColumns 设置为 JoinColumn(请参阅 @JoinColumn)的一个或多个实例。

name

默认值:JPA 持续性提供程序通过使用下划线连接关联主表(拥有方优先)的表名来命名连接表。

如果这样的连接表难于处理、是一个保留字或与预先存在的数据模型不兼容,则将 name 设置为相应的连接表名。在示例 1-45 中,JPA 使用名为 EJB_PROJ_EMP 的连接表。

schema

默认值:空 String。

默认情况下,JPA 使用任何适用于数据库的默认模式。

如果默认模式不适合于应用程序,则将 schema 设置为要使用的 String 模式名。

uniqueConstraints

默认值:UniqueConstraint 的空数组。

默认情况下,JPA 持续性提供程序假设连接表中的任何列均没有唯一约束。

如果唯一约束应用于该表中的一列或多列,则将 uniqueContraints 设置为一个或多个 UniqueConstraint 实例的数组。有关详细信息,请参阅 @UniqueConstraint

示例 1-45 显示了如何使用此批注为 Employee 与 Project 之间实体的多对多关系指定一个名为 EMP_PROJ_EMP 的连接表。连接表中有两列:EMP_ID 和 PROJ_ID。EMP_ID 列包含其主键列(被引用列)名为 ID 的 Employee 表中的主键值。PROJ_ID 列包含其主键列(被引用列)也名为 ID 的 Project 表中的主键值。

示例 1-45 @JoinTable

@Entitypublic class Employee implements Serializable { ...@ManyToMany@JoinTable(name="EJB_PROJ_EMP",joinColumns=@JoinColumn(name="EMP_ID", referencedColumnName="ID"),inverseJoinColumns=@JoinColumn(name="PROJ_ID", referencedColumnName="ID") )public Collection getProjects() {return projects; } ...}

@Lob

默认情况下,JPA 持续性提供程序假设所有持久数据均可以表示为典型的数据库数据类型。

结合使用 @Lob 批注与 @Basic 映射,以指定持久属性或字段应作为大型对象持久保存到数据库支持的大型对象类型。

Lob 可以是二进制类型或字符类型。持续性提供程序从持久字段或属性的类型推断出 Lob 类型。

对于基于字符串和字符的类型,默认值为 Clob。在所有其他情况下,默认值为 Blob。

还可以使用 @Column 属性 columnDefinition 进一步改进 Lob 类型。

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

示例 1-46 显示了如何使用此批注指定持久字段 pic 应作为 Blob 进行持久保存。

示例 1-46 @Lob

@Entitypublic class Employee implements Serializable { ...@Lob @Basic(fetch=LAZY)@Column(name="EMP_PIC", columnDefinition="BLOB NOT NULL")protected byte[] pic; ...}

 

@ManyToMany

默认情况下,JPA 为具有多对多多重性的为多值关联自动定义一个 @ManyToMany 映射。

使用 @ManyToMany 批注:

将获取类型配置为 LAZY

如果空值不适合于应用程序,则将映射配置为禁止空值(针对非基元类型)

由于所使用的 Collection 不是使用一般参数定义的,因此配置关联的目标实体

配置必须层叠到关联目标的操作:例如,如果删除了拥有实体,则确保还删除关联的目标

配置由持续性提供程序使用的连接表的详细信息(请参阅 @JoinTable

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

表 1-22 @ManyToMany 属性

属性必需说明

cascade

默认值:CascadeType 的空数组。

默认情况下,JPA 不会将任何持续性操作层叠到关联的目标。

如果希望某些或所有持续性操作层叠到关联的目标,请将 cascade 设置为一个或多个 CascadeType 实例,其中包括:

ALL — 针对拥有实体执行的任何持续性操作均层叠到关联的目标。

MERGE — 如果合并了拥有实体,则将 merge 层叠到关联的目标。

PERSIST — 如果持久保存拥有实体,则将 persist 层叠到关联的目标。

REFRESH — 如果刷新了拥有实体,则 refresh 为关联的层叠目标。

REMOVE — 如果删除了拥有实体,则还删除关联的目标。

fetch

默认值:FetchType.EAGER。

默认情况下,JPA 持续性提供程序使用获取类型 EAGER:这将要求持续性提供程序运行时必须迫切获取数据。

如果这不适合于应用程序或特定的持久字段,请将 fetch 设置为 FetchType.LAZY:这将提示持续性提供程序在首次访问数据(如果可以)时应不急于获取数据。

mappedBy

默认值:如果关系是单向的,则 JPA 持续性提供程序确定拥有该关系的字段。

如果关系是双向的,则将关联的反向(非拥有)一方上的 mappedBy 属性设置为拥有该关系的字段或属性的名称(如示例 1-48 所示)。

targetEntity

默认值:使用一般参数定义的 Collection 的参数化类型。

默认情况下,如果使用通过一般参数定义的 Collection,则持续性提供程序将从被引用的对象类型推断出关联的目标实体。

如果 Collection 不使用一般参数,则必须指定作为关联目标的实体类:将关联拥有方上的 targetEntity 元素设置为作为关系目标的实体的 Class。

示例 1-47示例 1-48 显示了如何使用此批注在使用一般参数的 Customer 和 PhoneNumber 之间配置一个多对多映射。

示例 1-47 @ManyToMany — 使用一般参数的 Customer 类

@Entitypublic class Customer implements Serializable { ...@ManyToMany@JoinTable(name="CUST_PHONE",joinColumns=@JoinColumn(name="CUST_ID", referencedColumnName="ID"),inverseJoinColumns=@JoinColumn(name="PHONE_ID", referencedColumnName="ID") )public Set<PhoneNumber> getPhones() { return phones; } ...}

示例 1-48 @ManyToMany — 使用一般参数的 PhoneNumber 类

@Entitypublic class PhoneNumber implements Serializable { ...@ManyToMany(mappedBy="phones")public Set<Customer> getCustomers() { return customers; } ...}

@ManyToOne

默认情况下,JPA 为指向具有多对一多重性的其他实体类的单值关联自动定义一个 ManyToOne 映射。

使用 @ManyToOne 批注:

将获取类型配置为 LAZY

如果空值不适合于应用程序,则将映射配置为禁止空值(针对非基元类型)

配置关联的目标实体(如果无法从被引用的对象类型推断出它)

配置必须层叠到关联目标的操作:例如,如果删除了拥有实体,则确保还删除关联的目标

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

表 1-23 @ManyToOne 属性

属性必需说明

cascade

默认值:CascadeType 的空数组。

默认情况下,JPA 不会将任何持续性操作层叠到关联的目标。

如果希望某些或所有持续性操作层叠到关联的目标,请将 cascade 设置为一个或多个 CascadeType 实例,其中包括:

ALL — 针对拥有实体执行的任何持续性操作均层叠到关联的目标。

MERGE — 如果合并了拥有实体,则将 merge 层叠到关联的目标。

PERSIST — 如果持久保存拥有实体,则将 persist 层叠到关联的目标。

REFRESH — 如果刷新了拥有实体,则 refresh 为关联的层叠目标。

REMOVE — 如果删除了拥有实体,则还删除关联的目标。

fetch

默认值:FetchType.EAGER。

默认情况下,JPA 持续性提供程序使用获取类型 EAGER:这将要求持续性提供程序运行时必须迫切获取数据。

如果这不适合于应用程序或特定的持久字段,请将 fetch 设置为 FetchType.LAZY:这将提示持续性提供程序在首次访问数据(如果可以)时应不急于获取数据。

optional

默认值:true。

默认情况下,JPA 持续性提供程序假设所有(非基元)字段和属性的值可以为空。

如果这并不适合于您的应用程序,请将 optional 设置为 false。

targetEntity

默认值:JPA 持续性提供程序从被引用的对象类型推断出关联的目标实体

如果持续性提供程序无法推断出目标实体的类型,则将关联拥有方上的 targetEntity 元素设置为作为关系目标的实体的 Class。

示例 1-49 显示了如何使用此批注在使用一般参数的 Customer(被拥有方)和 Order(拥有方)之间配置一个多对一映射。

示例 1-49 @ManyToOne

@Entitypublic class Order implements Serializable { ...@ManyToOne(optional=false)@JoinColumn(name="CUST_ID", nullable=false, updatable=false)public Customer getCustomer() {return customer; } ...}

@MapKey

默认情况下,JPA 持续性提供程序假设关联实体的主键为 java.util.Map 类型的关联的 Map 键:

如果主键是批注为 @Id 的非复合主键,则该字段或属性的类型实例将用作 Map 键。

如果主键是批注为 @IdClass 的复合主键,则主键类的实例将用作 Map 键。

使用 @MapKey 批注:

将某个其他字段或属性指定为 Map 键(如果关联实体的主键不适合于应用程序)

指定一个嵌入的复合主键类(请参阅 @EmbeddedId

指定的字段或属性必须具有唯一约束(请参阅 @UniqueConstraint)。

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

表 1-24 @MapKey 属性

属性必需说明

name

默认值:默认情况下,JPA 持续性提供程序将关联实体的主键作为 Map 键,以用于映射到非复合主键或复合主键(批注为 @IdClass)的 java.util.Map 的属性或字段。

如果要将某个其他字段或属性用作 Map 键,请将 name 设置为要使用的关联实体的 String 字段或属性名。

示例 1-52 中,Project 对作为 Map 的 Employee 实例拥有一对多关系。示例 1-52 显示了如何使用 @MapKey 批注指定此 Map 的键为 Employee 字段 empPK,它是一个类型为 EmployeePK(请参阅示例 1-52)的嵌入式复合主键(请参阅示例 1-51)。

示例 1-50 使用 @MapKey 的 Project 实体

@Entitypublic class Project { ...@OneToMany(mappedBy="project") @MapKey(name="empPK") public Map<EmployeePK, Employee> getEmployees() { ... } ...}

示例 1-51 Employee 实体

@Entitypublic class Employee { @EmbeddedId public EmployeePK getEmpPK() { ... } ... @ManyToOne @JoinColumn(name="proj_id") public Project getProject() { ... }...}

示例 1-52 EmployeePK 复合主键类

@Embeddablepublic class EmployeePK { String name; Date birthDate;}

@MappedSuperclass

默认情况下,JPA 持续性提供程序假设实体的所有持久字段均在该实体中定义。

使用 @MappedSuperclass 批注指定一个实体类从中继承持久字段的超类。当多个实体类共享通用的持久字段或属性时,这将是一个方便的模式。

您可以像对实体那样使用任何直接和关系映射批注(如 @Basic@ManyToMany)对该超类的字段和属性进行批注,但由于没有针对该超类本身的表存在,因此这些映射只适用于它的子类。继承的持久字段或属性属于子类的表。

可以在子类中使用 @AttributeOverride@AssociationOverride 批注来覆盖超类的映射配置。

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

示例 1-53 显示了如何使用此批注将 Employee 指定为映射超类。示例 1-54 显示了如何扩展实体中的此超类,以及如何在实体类中使用 @AttributeOverride 以覆盖超类中设置的配置。

示例 1-53 @MappedSuperclass

@MappedSuperclasspublic class Employee {@Idprotected Integer empId;@Versionprotected Integer version;@ManyToOne@JoinColumn(name="ADDR")protected Address address;public Integer getEmpId() { ... }public void setEmpId(Integer id) { ... }public Address getAddress() { ... }public void setAddress(Address addr) { ... }}

示例 1-54 扩展 @MappedSuperclass

@Entity@AttributeOverride(name="address", column=@Column(name="ADDR_ID"))public class PartTimeEmployee extends Employee {@Column(name="WAGE")protected Float hourlyWage;public PartTimeEmployee() { ... }public Float getHourlyWage() { ... }public void setHourlyWage(Float wage) { ... }}

@NamedNativeQueries

如果需要指定多个 @NamedNativeQuery,则必须使用一个 @NamedNativeQueries 批注指定所有命名查询。

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

表 1-25 @NamedNativeQueries 属性

属性必需说明

value

要指定两个或更多属性覆盖,请将 value 设置为 NamedNativeQuery 实例数组(请参阅 @NamedNativeQuery)。

示例 1-6 显示了如何使用此批注指定两个命名原生查询。

示例 1-55 @NamedNativeQueries

@Entity@NamedNativeQueries({@NamedNativeQuery(name="findAllPartTimeEmployees",query="SELECT * FROM EMPLOYEE WHERE PRT_TIME=1" ),@NamedNativeQuery(name="findAllSeasonalEmployees",query="SELECT * FROM EMPLOYEE WHERE SEASON=1" )})public class PartTimeEmployee extends Employee { ...}

@NamedNativeQuery

在使用 JPA 持续性提供程序的应用程序中,可以使用实体管理器动态创建和执行查询,也可以预定义查询并在运行时按名称执行。

使用 @NamedNativeQuery 批注创建与 @Entity@MappedSuperclass 关联的预定义查询,这些查询:

使用基础数据库的原生 SQL

经常被使用

比较复杂并且难于创建

可以在不同实体之间共享

返回实体、标量值或两者的组合(另请参阅 @ColumnResult@EntityResult@FieldResult@SqlResultSetMapping

如果有多个要定义的 @NamedNativeQuery,则必须使用 @NamedNativeQueries

要预定义适合于任何数据库的可移植查询,请参阅 @NamedQuery

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

表 1-26 @NamedNativeQuery 属性

属性必需说明

query

要指定查询,请将 query 设置为 SQL 查询(作为 String)。

有关原生 SQL 查询语言的详细信息,请参阅数据库文档。

hints

默认值:空 QueryHint 数组。

默认情况下,JPA 持续性提供程序假设 SQL 查询应完全按照 query 属性提供的方式执行。

要微调查询的执行,可以选择将 hints 设置为一个 QueryHint 数组(请参阅 @QueryHint)。在执行时,EntityManager 将向基础数据库传递提示。

name

要指定查询名称,请将 name 设置为所需的 String 名称。

这是您在运行时调用查询所使用的名称(请参阅示例 1-60)。

resultClass

默认值:JPA 持续性提供程序假设结果类是关联实体的 Class。

要指定结果类,请将 resultClass 设置为所需的 Class。

resultSetMapping

默认值:JPA 持续性提供程序假设原生 SQL 查询中的 SELECT 语句:返回一个类型的实体;包括与返回的实体的所有字段或属性相对应的所有列;并使用与字段或属性名称(未使用 AS 语句)相对应的列名。

要控制 JPA 持续性提供程序如何将 JDBC 结果集映射到实体字段或属性以及标量,请通过将 resultSetMapping 设置为所需的 @SqlResultSetMapping 的 String 名称来指定结果集映射。

示例 1-59 显示了如何使用 @NamedNativeQuery 批注定义一个使用基础数据库的原生 SQL 的查询。示例 1-60 显示了如何使用 EntityManager 获取此查询以及如何通过 Query 方法 getResultList 执行该查询。

示例 1-56 使用 @NamedNativeQuery 实现一个 Oracle 层次查询

@Entity@NamedNativeQuery(name="findAllEmployees",query="SELECT * FROM EMPLOYEE")public class Employee implements Serializable { ...}

示例 1-57 执行一个命名原生查询

Query queryEmployees = em.createNamedQuery("findAllEmployees");Collection employees = queryEmployees.getResultList();

@NamedQueries

如果需要指定多个 @NamedQuery,则必须使用一个 @NamedQueries 批注指定所有命名查询。

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

表 1-27 @NamedQueries 属性

属性必需说明

value

要指定两个或更多属性覆盖,请将 value 设置为 NamedQuery 实例数组(请参阅 @NamedQuery)。

示例 1-6 显示了如何使用此批注指定两个命名查询。

示例 1-58 @NamedQueries

@Entity@NamedQueries({@NamedQuery(name="findAllEmployeesByFirstName",query="SELECT OBJECT(emp) FROM Employee emp WHERE emp.firstName = :firstname" 相关资源:敏捷开发V1.0.pptx
转载请注明原文地址: https://www.6miu.com/read-4933056.html

最新回复(0)