ormDAO

Java技术指南「JPA编程专题」让你不再对JPA技术中的“持久

2021-09-25  本文已影响0人  洛神灬殇

JPA的介绍分析

JPA注解总览


image
image

JPA实体型注解

@Entity

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

image

@Table

默认情况下,JPA持续性提供程序假设实体的所有持久字段均存储到一个名称为实体名称的数据库表中(请参阅 @Entity )。 在以下条件下,使用 @Table注解可以指定与实体关联的主表:

实体名称难于处理、是一个保留字、与预先存在的数据模型不兼容或作为数据库中的表名无效需要控制表所属的目录或模式。

如果希望 JPA 将某些字段持久保存到主表,而将其他字段持久保存到一个或多个辅助表,请参阅@SecondaryTable 。 下表列出了此批注的属性。有关更多详细信息,请参阅 API 。

image
@Entity
@Table(name="Model") 
public class JavaModel implements Serializable {
    ...
}

@TableGenerator

@TableGenerator 属性
image
image

显示了如何使用此注解为名为 empGen 的 TABLE 主键生成器指定分配大小。

@TableGenerator
@Entity
public class Employee implements Serializable {  
    @Id 
    @TableGenerator( 
        name="empGen", 
        allocationSize=1 
    ) 
  @GeneratedValue(strategy=TABLE, generator="empGen") 
  @Column(name="CUST_ID") 
   public Long getId() { 
        return id; 
    } 
    ... 

@Temporal

使用 @Temporal 注解指定 JPA 的提供程序应只为 java.util.Date 和 java.util.Calendar 类型的字段或属性持久保存的数据库类型,可以与 @Basic 一起使用。


image

示例,显示了如何使用此批注指定 JPA 持续性提供程序应将 java.util.Date 字段 startDate 持久保存为 DATE ( java.sql.Date ) 数据库类型。

@Entity
public class Employee {
    @Temporal(DATE)
    protected java.util.Date startDate;
    ...
}

@Transient

@Entity
public class Employee {    
    @Id
    int id;    
    @Transient 
    Session currentSession;    
...} 

@Column

默认情况下,JPA 持续性提供程序假设每个实体的持久字段存储在其名称与持久字段的名称相匹配的数据库表列中。
使用 @Column 批注:
将持久字段与其他名称关联(如果默认列名难于处理、与事先存在的数据模型不兼容或作为数据库中的列名无效)
将持久字段与辅助表中的列关联(请参阅 @SecondaryTable )
微调数据库中列的特征

@Column 属性

image
image
image

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

@Column

@Entity
@SecondaryTable(name="EMP_HR")
public class Employee implements Serializable {  

    @Column(name="EMP_NUM", table="EMP_HR")
    private Long empId;
    private String empName;
}

@UniqueConstraint

默认情况下,JPA持久化提供程序假设所有列均可以包含重复值。

使用@UniqueConstraint注解指定将在为主表或辅助表生成的DDL中包含一个唯一约束,或者,您可以在列级别指定唯一约束。

属性状态
image

显示了如何使用此注解对主表 EMP 中的列 EMP_ID 和 EMP_NAME 指定一个唯一约束,使用唯一约束的 @Table。

@Entity
@Table(
name="EMP",
uniqueConstraints={@UniqueConstraint(columnNames={"EMP_ID", "EMP_NAME"})}
)
public class Employee implements Serializable {
    ...
}

@Version

默认情况下,JPA持久化提供程序假设应用程序负责数据一致性。

使用@Version注解通过指定用作其乐观锁定值的实体类的版本字段或属性来启用 JPA 管理的乐观锁定(推荐做法)。

如何使用此注解将属性getVersionNum指定为乐观锁定值。在该示例中,该属性的列名设置为OPTLOCK(请参阅 @Column ),而非属性的默认列名。

@Version

@Entity 
public class Employee implements Serializable {
    ...
    @Version
    @Column(name="OPTLOCK")
    protected int getVersionNum() {
        return versionNum;
    }
    ...
}

@Embeddable 和 @Embedded

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

@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 对象类型组成)。从原有数据库映射时(此时数据库键由多列组成),通常将出现复合主键。

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

@Embeddable
public class EmployeePK implements Serializable{
    private String name;
    private long id;
    public EmployeePK()  {    }
    //setter and getter
    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);
        }
    }

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

@MappedSuperclass

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

@MappedSuperclass
public class Employee {
@Id
protected Integer empId;
 
@Version
protected 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) { 
        ... 
    }
}

@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) { 
        ... 
    }
}

@EntityListeners

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

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

@EntityListeners 属性

image

显示了您可以将多个生命周期事件与给定的实体监听程序类方法关联,但任何给定的生命周期事件只能在实体监听程序类中出现一次。

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

    public class EmployeePersistListener {
    @PrePersist
    public void employee PrePersist(Object employee) {}};

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

@ExcludeDefaultListeners

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

    @Entity
    @ExcludeDefaultListeners
    public class Employee implements Serializable {    ...} 
上一篇下一篇

猜你喜欢

热点阅读