使用@AttributeOverride覆盖列定义

2023/05/18

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。它演示了如何扩展实体并将汽车的信息存储在单个表中。请注意,@AttributeOverride注解在类上指定

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

    // standard getters and setters
}

因此,我们有一张包含所有Car详细信息和Vehicle详细信息的表。问题是对于Car,我们希望在VIN列中存储identifier。我们通过@AttributeOverride实现了这一点。该注解用于定义字段identifier存储在VIN列中

4. 与@Embeddable一起使用

现在让我们使用两个可嵌入类向我们的车辆添加更多详细信息。

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

@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与多级嵌入一起使用

下面在我们的Car实体中添加Brand字段:

@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类中的name列定义,因为Car类中存在名称相同的列。因此,Brand的name属性存储在BRAND_NAME列中。

此外,我们定义了BRAND_NAME列长度。请注意,column属性会覆盖被覆盖类中的所有值。要保留原始值,必须在column属性中设置所有值。

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

5. 嵌入集合

让我们来看看如何将该注解与集合一起使用。

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

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

    // standard getters and setters
}

我们希望将车主与地址信息关联在一起,所以让我们添加一个所有者及其地址的Map字段:

@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类。在上面的@AttributeOverride注解中,name属性的key前缀表示覆盖Owner类中的字段。此外,name属性的value前缀指向Address类中的字段。对于List集合,不需要添加这些前缀。

6. 总结

这篇关于@AttibuteOverride注解的短文到此结束。我们已经了解了如何在@MappedSuperclass或@Embeddable实体时使用此注解。之后,我们学习了如何将它用于集合。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章