2013年05月18日

核心提示:JPA 注解的几个要点 1.设置Pojo为实体 @Entity //标识这个pojo是一个jpa实体 public class Users implements Serializable{ } 2.设置表名 @Entity @Table (name= users ) //指定表名为users public class Users implements Serializable{ } 3.设置主键 public
JPA 注解的几个要点

1.设置Pojo为实体


@Entity //标识这个pojo是一个jpa实体    
public class Users implements Serializable {    
  


2.设置表名


@Entity    
@Table(name = "users") //指定表名为users    
public class Users implements Serializable {    
  


3.设置主键


public class Users implements Serializable {    
@Id    
private String userCode;   


4. 设置字段类型
通过@Column注解设置,包含的设置如下
.name:字段名
.unique:是否唯一
.nullable:是否可以为空
.inserttable:是否可以插入
.updateable:是否可以更新
.columnDefinition: 定义建表时创建此列的DDL
.secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字。


@Column(name = "user_code", nullable = false, length=32)//设置属性userCode对应的字段为user_code,长度为32,非空    
private String userCode;    
@Column(name = "user_wages", nullable = true, precision=12, scale=2)//设置属性wages对应的字段为user_wages,12位数字可保留两位小数,可以为空    
private double wages;    
@Temporal(TemporalType.DATE)//设置为时间类型    
private Date joinDate;   

 

5.字段排序
在加载数据的时候可以为其指定顺序,使用@OrderBy注解实现


@Table(name = "USERS")    
public class User {    
@OrderBy(name = "group_name ASC, name DESC")    
private List books = new ArrayList();    
  


6.主键生成策略


public class Users implements Serializable {    
@Id    
@GeneratedValue(strategy=GenerationType.IDENTITY)//主键自增,注意,这种方式依赖于具体的数据库,如果数据库不支持自增主键,那么这个类型是没法用的    
@Column(name = "user_id", nullable = false)    
private int userId;    
  
  
public class Users implements Serializable {    
@Id    
@GeneratedValue(strategy=GenerationType.TABLE)//通过一个表来实现主键id的自增,这种方式不依赖于具体的数据库,可以解决数据迁移的问题    
@Column(name = "user_code", nullable = false)    
private String userCode;    
  
  
public class Users implements Serializable {    
@Id    
@GeneratedValue(strategy=GenerationType.SEQUENCE)//通过Sequence来实现表主键自增,这种方式依赖于数据库是否有SEQUENCE,如果没有就不能用    
@SequenceGenerator(name="seq_user")    
@Column(name = "user_id", nullable = false)    
private int userId;   

 

7.一对多映射关系
有T_One和T_Many两个表,他们是一对多的关系,注解范例如下
主Pojo


@Entity    
@Table(name = "T_ONE")    
public class One implements Serializable {    
private static final long serialVersionUID = 1L;    
@Id    
@Column(name = "ONE_ID", nullable = false)    
private String oneId;    
@Column(name = "DESCRIPTION")    
private String description;    
@OneToMany(cascade = CascadeType.ALL, mappedBy = "oneId")//指向多的那方的pojo的关联外键字段    
private Collection manyCollection;    


子Pojo


@Entity    
@Table(name = "T_MANY")    
public class Many implements Serializable {    
private static final long serialVersionUID = 1L;    
@Id    
@Column(name = "MANY_ID", nullable = false)    
private String manyId;    
@Column(name = "DESCRIPTION")    
private String description;    
  
@JoinColumn(name = "ONE_ID", referencedColumnName = "ONE_ID")//设置对应数据表的列名和引用的数据表的列名    
@ManyToOne//设置在“一方”pojo的外键字段上    
private One oneId;    

 

8.多对多映射关系
貌似多对多关系不需要设置级联,以前用hibernate的时候着实为多对多的级联头疼了一阵子,JPA的多对多还需要实际的尝试一下才能有所体会。
估计JPA的多对多也是可以转换成两个一对多的。

第一个Pojo


@Entity    
@Table(name = "T_MANYA")    
public class ManyA implements Serializable {    
private static final long serialVersionUID = 1L;    
@Id    
@Column(name = "MANYA_ID", nullable = false)    
private String manyaId;    
@Column(name = "DESCRIPTION")    
private String description;    
@ManyToMany    
@JoinTable(name = "TMANY1_TMANY2", joinColumns = {@JoinColumn(name = "MANYA_ID", referencedColumnName = "MANYA_ID")}, inverseJoinColumns = {@JoinColumn(name = "MANYB_ID", referencedColumnName = "MANYB_ID")})    
private Collection manybIdCollection;    


第二个Pojo


@Entity    
@Table(name = "T_MANYB")    
public class ManyB implements Serializable {    
private static final long serialVersionUID = 1L;    
@Id    
@Column(name = "MANYB_ID", nullable = false)    
private String manybId;    
@Column(name = "DESCRIPTION")    
private String description;    
@ManyToMany(mappedBy = "manybIdCollection")    
private Collection manyaIdCollection;    

 

9.一对一映射关系
主Pojo


@Entity    
@Table(name = "T_ONEA")    
public class OneA implements Serializable {    
private static final long serialVersionUID = 1L;    
@Id    
@Column(name = "ONEA_ID", nullable = false)    
private String oneaId;    
@Column(name = "DESCRIPTION")    
private String description;    
@OneToOne(cascade = CascadeType.ALL, mappedBy = "oneA")//主Pojo这方的设置比较简单,只要设置好级联和映射到从Pojo的外键就可以了。    
private OneB oneB;   

从Pojo


@Entity    
@Table(name = "T_ONEB")    
public class OneB implements Serializable {    
private static final long serialVersionUID = 1L;    
@Id    
@Column(name = "ONEA_ID", nullable = false)    
private String oneaId;    
@Column(name = "DESCRIPTION")    
private String description;    
@JoinColumn(name = "ONEA_ID", referencedColumnName = "ONEA_ID", insertable = false, updatable = false)//设置从方指向主方的关联外键,这个ONEA_ID其实是表T_ONEA的主键    
@OneToOne    
private OneA oneA;    

 

10 大字段


@Lob //对应Blob字段类型    
@Column(name = "PHOTO")    
private Serializable photo;    
@Lob //对应Clob字段类型    
@Column(name = "DESCRIPTION")    
private String description;   

 

11.瞬时字段
不需要与数据库映射的字段,在保存的时候不需要保存倒数据库


@Transient    
private int tempValue;    
  
public int getTempValue(){    
get tempValue;    
   
  
public void setTempValue(int value){    
this.tempValue = value;    
  

 

java代码

JPA注解
关键字: jpa注解
@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
执行

使用 @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
默认情况下,当

使用 @DiscriminatorColumn 批注:

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

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

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

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

表 1-9 @DiscriminatorColumn 属性

属性 必需 说明
columnDefinition
 

 默认值 :空 String 。

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

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

 默认值 :DiscriminatorType.STRING 。

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

如果要使用其他类型,请将 discriminatorType 设置为 DiscriminatorType.CHAR 或 DiscriminatorType.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 。在 Customer 和 ValuedCustomer 中,@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
默认情况下,当

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

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

匹配现有的数据库模式

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

表 1-10 @DiscriminatorValue 属性

属性 必需 说明
value
 

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

示例 1-14 显示了如何使用此批注指定一个名为 DISC 、类型为 STRING 、长度为 20 的标识符列。在本示例中,该类的 @DiscriminatorValue 指定为 CUST 。示例 1-15 中的子类将它自己的 @DiscriminatorValue 指定为 VIP 。在 Customer 和 ValuedCustomer 中,@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 批注指定一个类,该类的实例存储为拥有实体的固有部分并共享该实体的身份。嵌入对象的每个持久属性或字段都将映射到实体的数据库表。

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

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

示例 1-16 @Embeddable

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


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

使用 @Embedded 批注指定一个持久字段,该字段的

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

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

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

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

示例 1-17 显示了如何使用该批注指定:@Embeddable 类 EmploymentPeriod (请参阅示例 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。

它必须是可序列化的。

它必须定义 equals 和 hashCode 方法。

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

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

此批注没有属性 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 @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 (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
执行

使用 @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 显示了如何使用此批注将 Order 和 Item (请参阅示例 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 一起使用。



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



生命周期事件批注 )指定实体中的方法,这些方法在指定的生命周期事件发生时执行您的逻辑。

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


@IdClass )。

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

API 。


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


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



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

JPA作为Java EE的规范,它只是提供了一种标准的API。程序员若要使用JPA,仍需要选择JPA的实现框架。通过本章的学习,读者将能够了解与不同的JPA实现框架相关的知识,以便在实际的项目中做出合适的选择。

Hibernate是最流行的ORM框架之一,也是最早实现JPA的规范框架之一。它被JBoss收购后,目前作为JBoss的一个开源框架,它遵循LGPL v2.1开源许可协议,官方主页是http://www.hibernate.org/

Hibernate 3.2以及以后的版本开始支持JPA,如图14-1所示为Hibernate框架包含的所有子项目。其中,涉及JPA的子项目有三个,它们分别是:

·Hibernate Core:Hibernate框架的核心实现。

·Hibernate Annotations:支持JDK 5.0的注释。

·Hibernate EntityManager:支持JPA的实现。

Hibernate JPA自定义配置可以通过多种方式进行配置,如下面列举的几种方法。

·方法一:在persistence.xml文件中配置,如下所示。

java代码:

  1.   
  2. "jpaUnit"  transaction-type="RESOURCE_LOCAL">   
  3. org.hibernate.ejb.HibernatePersistence   
  4.   
  5. "hibernate.connection.driver_class"value="com.mysql.jdbc.Driver" />   
  6. "hibernate.connection.url"value="jdbc:mysql://localhost:3306/jpademo" />   
  7. "hibernate.connection.username" value="root" />   
  8. hibernate.show_sql " value="true"/>   
  9.     
  10.   
  11.   

其中,“hibernate.show_sql ”为可配置的属性,Hibernate JPA还提供很多不同属性的配置。

·方法二:通过代码,在创建EntityManagerFactory时指定,如下所示。

Map configOverrides = new HashMap();
configOverrides.put("hibernate.format_sql ", true);
EntityManagerFactory programmaticEmf =
Persistence.createEntityManagerFactory("jpaUnit", configOverrides

当同时使用方法一和方法二设置时,方法二的方式为有效的配置。

·方法三:使用Hibernate 专有的配置文件来配置,但首先要在persistence.xml文件中配置“hibernate.ejb.cfgfile”指定配置文件的位置,如下所示。

  1. <</SPAN>persistence>  
  2. <</SPAN>persistence-unit name="jpaUnit"  transaction-type="RESOURCE_LOCAL">  
  3. <</SPAN>provider>org.hibernate.ejb.HibernatePersistence</</SPAN>provider>  
  4. <</SPAN>properties>  
  5. <</SPAN>property name="hibernate.connection.driver_class"value="com.mysql.jdbc.Driver" />  
  6. <</SPAN>property name="hibernate.connection.url"value="jdbc:mysql://localhost:3306/jpademo" />  
  7. <</SPAN>property name="hibernate.connection.username" value="root" />  
  8. >     
  9. <</SPAN> property name="hibernate.ejb.cfgfile" value="/com/fengmanfei/jpa/hibernate.cfg.xml">  
  10. </</SPAN>properties>    
  11. </</SPAN>persistence-unit>  
  12. </</SPAN>persistence
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

huangleijay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值