2008年(60)
分类: Java
2008-04-28 09:29:32
默认情况下,JPA 持续性提供程序假设 或 应完全按照查询 String
指定的方式执行。
使用 @QueryHint
批注指定供应商特定的 JPA 查询扩展,以:
提高查询性能
利用供应商的 JPA 持续性提供程序实现中的特定特性
列出了此批注的属性。有关更多详细信息,请参阅 。
表 1-39 @QueryHint 属性
属性 | 必需 | 说明 |
---|---|---|
|
|
要指定提示名称,请将 有关提示的详细信息,请参阅 JPA 持续性提供程序文档。 |
|
|
要指定提示的值,请将 有关提示值的详细信息,请参阅 JPA 持续性提供程序文档。 |
显示了如何使用 @QueryHint
批注自定义查询以利用由 TopLink Essentials 提供的供应商 JPA 扩展:在该示例中,提示确保在执行查询时始终刷新 TopLink 缓存。有关详细信息,请参阅。
示例 1-77 @QueryHint
@Entity @NamedQuery( name="findAllEmployees", query="SELECT * FROM EMPLOYEE WHERE MGR=1" hints={@QueryHint={name="toplink.refresh", value="true"}} ) public class Employee implements Serializable { ... }
默认情况下,JPA 持续性提供程序假设实体的所有持久字段均存储到一个名称为实体名称的数据库表中:该表称作主表(请参阅 )。
如果希望 JPA 分别将实体的某些持久字段持久保存到主表和其他数据库表,请使用 @SecondaryTable
批注将实体与其他数据库表关联。在该示例中,您使用 批注将实体的持久字段与表关联。
如果要将两个或更多辅助表与实体关联,则可以使用 。
列出了此批注的属性。有关更多详细信息,请参阅 。
表 1-40 @SecondaryTable 属性
属性 | 必需 | 说明 |
---|---|---|
|
|
如果实体使用辅助表,请将 |
|
|
默认值:JPA 持续性提供程序使用任何适用于数据库的默认目录。 如果默认目录不适合于应用程序,请将 |
|
|
默认值:JPA 持续性提供程序假设实体的数据库表中的任何列均不用于主键连接。 如果对该表中的主键连接使用一个或多个列,请将 |
|
|
默认值:JPA 持续性提供程序使用任何适用于数据库的默认模式。 如果默认模式不适合于应用程序,请将 |
|
|
默认值:JPA 持续性提供程序假设实体的数据库表中的任何列均没有唯一约束。 如果唯一约束应用于该表中的一列或多列,请将 |
显示了如何使用此批注指定一个名为 EMP_HR
的辅助表。在该示例中,默认情况下,JPA 将实体持久字段 empId
持久保存到名为 Employee
的主表中的列 empId
,并将 empSalary
持久保存到辅助表 EMP_HR
中的列 empSalary
。有关详细信息,请参阅 。
示例 1-78 @SecondaryTable
@Entity @SecondaryTable(name="EMP_HR") public class Employee implements Serializable { ... private Long empId; @Column(table="EMP_HR", name="EMP_SALARY")) private Float empSalary; ... }
如果需要指定多个 ,可以使用一个 @SecondaryTables
批注指定所有辅助表。
列出了此批注的属性。有关更多详细信息,请参阅 。
表 1-41 @SecondaryTables 属性
属性 | 必需 | 说明 |
---|---|---|
|
|
要指定两个或更多辅助表,请将 |
显示了如何使用此批注指定两个名为 EMP_HR
和 EMP_TR
的辅助表。在该示例中,默认情况下,JPA 将实体持久字段 empId
持久保存到名为 Employee
的主表中的列 empId
。JPA 将 empSalary
持久保存到辅助表 EMP_HR
中的列 empSalary
,并将 empClass
持久保存到辅助表 EMP_TR
中的列 EMP_HR
。有关详细信息,请参阅 。
示例 1-79 @SecondaryTables
@Entity @SecondaryTables({ @SecondaryTable(name="EMP_HR"), @SecondaryTable(name="EMP_TR") }) public class Employee implements Serializable { ... private Long empId; @Column(table="EMP_HR", name="EMP_SALARY")) private Float empSalary; @Column(table="EMP_TR", name="EMP_CLASS")) private Float empClass; ... }
如果使用 批注指定一个 SEQUENCE
类型的主键生成器,则可以使用 @SequenceGenerator
批注微调该主键生成器以:
更改分配大小以匹配应用程序要求或数据库性能参数
更改初始值以匹配现有的数据模型(例如,如果基于已经为其分配或保留了一组主键值的现有数据集构建)
使用现有数据模型中预定义的序列
列出了此批注的属性。有关更多详细信息,请参阅 。
表 1-42 @SequenceGenerator 属性
属性 | 必需 | 说明 |
---|---|---|
|
|
|
|
|
默认值: 50. 默认情况下,JPA 持续性提供程序使用的分配大小为 50。 如果此分配大小与应用程序要求或数据库性能参数不匹配,请将 |
|
|
默认值: 0. 默认情况下,JPA 持续性提供程序假设持续性提供程序将所有主键值的起始值设置为 0。 如果这与现有数据模型不匹配,请将 |
|
|
默认值:JPA 持续性提供程序分配它自己创建的序列名。 如果要使用事先存在或预定义的序列,请将 |
显示了如何使用此批注为名为 CUST_SEQ
的 SEQUENCE
主键生成器指定分配大小。
示例 1-80 @SequenceGenerator
@Entity public class Employee implements Serializable { ... @Id @SequenceGenerator(name="CUST_SEQ", allocationSize=25) @GeneratedValue(strategy=SEQUENCE, generator="CUST_SEQ") @Column(name="CUST_ID") public Long getId() { return id; } ...
执行 时,它可以返回实体(包括不同类型的实体)、标量值或实体和标量值的组合。
默认情况下(如 所示),JPA 持续性提供程序假设原生 SQL 查询中的 SELECT
语句:
返回一个实体类型
包含与返回的实体的所有字段或属性相对应的所有列
使用与字段或属性名(未使用 AS
语句)相对应的列名
示例 1-81 简单的原生 SQL 查询
Query q = entityManager.createNativeQuery( "SELECT o.id, o.quantity, o.item " + "FROM Order o, Item i " + "WHERE (o.item = i.id) AND (i.name = "widget")", Order.class ); List resultList = q.getResultList(); // List of Order entity objects:{Order, Order, ...}
如果原生 SQL 查询满足以下条件,请使用 @SqlResultSetMapping
批注控制 JPA 持续性提供程序如何将 JDBC 结果集映射到实体字段或属性以及标量:
返回多个类型的实体
只返回标量值或实体和标量值的组合
使用列别名(AS
语句)
如果有多个 @SqlResultSetMapping
,则必须使用 。
列出了此批注的属性。有关更多详细信息,请参阅 。
表 1-43 @SqlResultSetMapping 属性
属性 | 必需 | 说明 |
---|---|---|
|
|
将 这是用于将 |
|
|
默认值:空 默认情况下,JPA 持续性提供程序假设 如果 |
|
|
默认值:空 默认情况下,JPA 持续性提供程序假设 SELECT 语句返回一个类型的实体。 如果 SELECT 语句返回多个类型的实体,请将实体设置为 |
显示了如何使用此批注将 Order
和 Item
(请参阅)实体和标量 name
包含在结果列表(请参阅)中。在该示例中,结果列表将为 Object
数组的 List
,如:{[Order, Item, "Shoes"], [Order, Item, "Socks"], ...}
。
示例 1-82 使用 @SqlResultSetMapping 的 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"), } ) } columns={ @ColumnResult( name="item_name" ) } ) @Entity public class Order { @Id protected int id; protected long quantity; protected Item item; ... }
示例 1-83 Item 实体
@Entity public class Item { @Id protected int id; protected String name; ... }
示例 1-84 将 @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, "Shoes"], [Order, Item, "Socks"], ...}
如果需要指定多个 ,则必须使用一个 @SqlResultSetMappings
批注指定所有 SQL 结果集映射。
列出了此批注的属性。有关更多详细信息,请参阅 。
表 1-44 @SqlResultSetMappings 属性
属性 | 必需 | 说明 |
---|---|---|
|
|
要指定两个或更多 SQL 结果集映射,请将 |
显示了如何使用此批注指定两个 实例。
示例 1-85 @SqlResultSetMappings
SqlResultSetMappings({ @SqlResultSetMapping( name="OrderItemItemNameResults", entities={ @EntityResult(entityClass=Order.class), @EntityResult(entityClass=Item.class) } columns={ @ColumnResult(name="item_name") } ), @SqlResultSetMapping( name="OrderItemResults", entities={ @EntityResult(entityClass=Order.class), @EntityResult(entityClass=Item.class) } ) }) @Entity public class Order { @Id protected int id; protected long quantity; protected Item item; ... }