1. 概述

在本教程中,我们将展示如何使用 @AttributeOverride 更改列映射。我们将解释如何在扩展或嵌入实体时使用它,并且我们将介绍单个和集合嵌入。

2. @AttributeOverride 的属性

该注释包含两个强制属性:

  • name – 包含的实体的字段名称
  • column – 列定义覆盖原始对象中定义的列定义

3.与 @MappedSuperclass 一起使用

让我们定义一个 Vehicle 类*:*

@MappedSuperclass
public class Vehicle {
    @Id
    @GeneratedValue
    private Integer id;
    private String identifier;
    private Integer numberOfWheels;
    
    // standard getters and setters
}

@MappedSuperclass 注释表明它是其他实体的基类。

接下来让我们定义 Car 类,它扩展了 Vehicle。 它演示了如何扩展实体并将汽车的信息存储在单个表中。请注意,注释位于类上:

@Entity
@AttributeOverride(name = "identifier", column = @Column(name = "VIN"))
public class Car extends Vehicle {
    private String model;
    private String name;

    // standard getters and setters
}

因此,我们有一张表,其中包含所有汽车详细信息以及车辆详细信息。问题是,对于汽车,我们希望在 VIN 列中存储一个标识符。 我们通过 @AttributeOverride 来实现它。 该注释定义字段 标识符 存储在 VIN 列中。

4. 与嵌入式类一起使用

现在让我们通过两个可嵌入类向我们的车辆添加更多细节。

我们首先定义基本地址信息:

@Embeddable
public class Address {
    private String name;
    private String city;

    // standard getters and setters
}

我们还创建一个包含汽车制造商信息的类:

@Embeddable
public class Brand {
    private String name;
    private LocalDate foundationDate;
    @Embedded
    private Address address;

    // standard getters and setters
}

Brand 类包含一个带有地址详细信息的嵌入式类。 我们将用它来演示如何使用 @AttributeOverride 进行多级嵌入。

让我们用 品牌 详细信息扩展我们的 汽车

@Entity
@AttributeOverride(name = "identifier", column = @Column(name = "VIN"))
public class Car extends Vehicle {
    // existing fields

    @Embedded
    @AttributeOverrides({
      @AttributeOverride(name = "name", column = @Column(name = "BRAND_NAME", length = 5)),
      @AttributeOverride(name = "address.name", column = @Column(name = "ADDRESS_NAME"))
    })
    private Brand brand;

    // standard getters and setters
}

首先, @ AttributeOverrides 注解允许我们修改多个属性 。我们覆盖了 Brand 类中的 名称 列定义,因为 Car 类中存在相同的列。因此,品牌名称存储在 BRAND_NAME 列中。

此外, 我们定义了列长度以表明不仅可以覆盖列名称 。请注意, column 属性会覆盖被覆盖类中的所有值 。要保留原始值,必须在 属性*.*中全部设置

除此之外, Address 类中的 名称 列已映射到 ADDRESS_NAME为了覆盖多个嵌入级别的映射,我们使用点“.”。指定覆盖字段的路径

5. 嵌入式集合

让我们稍微研究一下这个注释,看看它如何与集合一起工作。

让我们添加车主详细信息:

@Embeddable
public class Owner {
    private String name;
    private String surname;

    // standard getters and setters
}

我们希望拥有一个所有者和一个地址,所以让我们添加一个所有者及其地址的地图*:*

@Entity
@AttributeOverride(name = "identifier", column = @Column(name = "VIN"))
public class Car extends Vehicle {
    // existing fields

    @ElementCollection
    @AttributeOverrides({
      @AttributeOverride(name = "key.name", column = @Column(name = "OWNER_NAME")),
      @AttributeOverride(name = "key.surname", column = @Column(name = "OWNER_SURNAME")),
      @AttributeOverride(name = "value.name", column = @Column(name = "ADDRESS_NAME")),
    })
    Map<Owner, Address> owners;

    // standard getters and setters
}

由于注释,我们可以重用 Address 前缀表示对 Owner 类中字段的覆盖。此外, 前缀指向 Address 类中的字段。对于列表,不需要添加前缀。

六,结论

关于 @AttibuteOverride 注释的这篇短文到此结束。我们已经了解了如何在扩展或嵌入实体时使用此注释。之后,我们学习了如何将它与集合一起使用。

与往常一样,该示例的源代码可以在 GitHub 上获取。