【Java技术指南】「JPA编程专题」让你不再对JPA技术中的“持久化型注解”感到陌生了(二)

简介: 【Java技术指南】「JPA编程专题」让你不再对JPA技术中的“持久化型注解”感到陌生了

【Java技术指南】「JPA编程专题」让你不再对JPA技术中的“持久化型注解”感到陌生了(一)https://developer.aliyun.com/article/1471007


@Column

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

@Column 属性


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

@Column

java

复制代码

@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中包含一个唯一约束,或者,您可以在列级别指定唯一约束。

属性状态

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

java

复制代码

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

@Version

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

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

  • 选择版本字段或属性时,确保:
  • 每个实体只有一个版本字段或属性
  • 选择一个持久保存到主表的属性或字段(请参阅 @Table )
  • 您的应用程序不修改版本属性或字段

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

@Version

java

复制代码

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

@Embeddable 和 @Embedded

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

java

复制代码

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

@Embedded

  • 使用 @Embedded 批注指定一个持久字段,该字段的 @Embeddable 类型可以存储为拥有实体的固有部分,并共享该实体的身份。
  • 嵌入对象的每个持久属性或字段均映射到拥有实体的数据库表。
  • 可以结合使用 @Embedded 和 @Embeddable 以建立严格所有权关系的模型,以便在删除了拥有对象的情况下还将删除被拥有的对象。嵌入的对象不应映射到多个表。
  • @Embeddable 类中指定的列定义适用于 @Embedded 类。
  • 如果要覆盖这些列定义,请使用 @AttributeOverride 。
  • @Embeddable 类 EmploymentPeriod可以使用指定的属性覆盖嵌入到实体类中。

java

复制代码

@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 方法。
  • 这些方法的值相等性的语义必须与键映射到的数据库类型的数据库相等性一致。

java

复制代码

@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

  • 使用 @MappedSuperclass 批注指定一个实体类从中继承持久字段的超类。当多个实体类共享通用的持久字段或属性时,这将是一个方便的模式。
  • 您可以像对实体那样使用任何直接和关系映射批注(如 @Basic 和 @ManyToMany)对该超类的字段和属性进行批注,但由于没有针对该超类本身的表存在,因此这些映射只适用于它的子类。继承的持久字段或属性属于子类的表。
  • 可以在子类中使用 @AttributeOverride 或 @AssociationOverride 批注来覆盖超类的映射配置。

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

java

复制代码

@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 关联,条件是您需要在指定的生命周期事件发生时执行逻辑。

  • 不希望在实体 API 中公开生命周期监听程序方法。
  • 要在不同的实体类型之间共享生命周期监听程序逻辑。
  • 当实体或子类上发生生命周期事件时,JPA 持续性提供程序将按监听程序定义的顺序通知每个实体监听程序,并调用使用相应的生命周期事件类型进行批注的实体监听程序方法(如果有)。

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

  • 它是一个普通的旧式 Java 对象 (POJO) 类
  • 它有一个或多个具有以下签名的回调方法:
  • public void (Object)
  • 可以指定参数类型 Object ,或实体监听程序将与其关联的实体类的类型。
  • 它用一个或多个生命周期事件批注对每个回调方法进行批注。
  • 一个生命周期事件只能与一个回调监听程序方法关联,但某个给定的回调监听程序方法可以与多个生命周期事件关联。
  • 如果使用实体监听程序,则可以管理哪些实体监听程序使用

@EntityListeners 属性

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

java

复制代码

@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 执行的默认监听程序。

java

复制代码

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


目录
打赏
0
1
1
0
375
分享
相关文章
单位网络监控软件:Java 技术驱动的高效网络监管体系构建
在数字化办公时代,构建基于Java技术的单位网络监控软件至关重要。该软件能精准监管单位网络活动,保障信息安全,提升工作效率。通过网络流量监测、访问控制及连接状态监控等模块,实现高效网络监管,确保网络稳定、安全、高效运行。
82 11
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
85 7
智慧产科一体化管理平台源码,基于Java,Vue,ElementUI技术开发,二开快捷
智慧产科一体化管理平台覆盖从备孕到产后42天的全流程管理,构建科室协同、医患沟通及智能设备互联平台。通过移动端扫码建卡、自助报道、智能采集数据等手段优化就诊流程,提升孕妇就诊体验,并实现高危孕产妇五色管理和孕妇学校三位一体化管理,全面提升妇幼健康宣教质量。
33 12
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
Java 并发编程——volatile 关键字解析
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
1463 1
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
java并发编程中Monitor里的waitSet和EntryList都是做什么的
在Java并发编程中,Monitor内部包含两个重要队列:等待集(Wait Set)和入口列表(Entry List)。Wait Set用于线程的条件等待和协作,线程调用`wait()`后进入此集合,通过`notify()`或`notifyAll()`唤醒。Entry List则管理锁的竞争,未能获取锁的线程在此排队,等待锁释放后重新竞争。理解两者区别有助于设计高效的多线程程序。 - **Wait Set**:线程调用`wait()`后进入,等待条件满足被唤醒,需重新竞争锁。 - **Entry List**:多个线程竞争锁时,未获锁的线程在此排队,等待锁释放后获取锁继续执行。
89 12
|
2月前
|
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
235 2
Java EE数据持久化框架mybatis练习——获取id值为1的角色信息。
Java EE数据持久化框架mybatis练习——获取id值为1的角色信息。
185 0
Java EE数据持久化框架mybatis练习——获取id值为1的角色信息。
批判Java持久化框架
批判Java持久化框架 原文写得很不错,详见:http://fromapitosolution.blogspot.com/2008/12/criticism-of-java-persistence.html。
910 0

热门文章

最新文章