3.2.2 注解域作为实体

很快就会看到,在创建存储库方面,Spring Data 做了一些惊人的事情。但不幸的是,在使用 JPA 映射注解注解域对象时,它并没有太大的帮助。需要打开 Ingredient、Taco 和 Order 类,并添加一些注解。首先是 Ingredient 类。

程序清单 3.16 为 JPA 持久化注解 Ingredient
package tacos;

import javax.persistence.Entity;
import javax.persistence.Id;
import lombok.AccessLevel;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;

@Data
@RequiredArgsConstructor
@NoArgsConstructor(access=AccessLevel.PRIVATE, force=true)
@Entity
public class Ingredient {
    @Id
    private final String id;
    private final String name;
    private final Type type;
    
    public static enum Type {
        WRAP, PROTEIN, VEGGIES, CHEESE, SAUCE
    }
}

为了将其声明为 JPA 实体,必须使用 @Entity 注解。它的 id 属性必须使用 @Id 进行注解,以便将其指定为惟一标识数据库中实体的属性。

除了特定于 JPA 的注解之外,还在类级别上添加了 @NoArgsConstructor 注解。JPA 要求实体有一个无参构造函数,所以 Lombok 的 @NoArgsConstructor 实现了这一点。但是要是不希望使用它,可以通过将 access 属性设置为 AccessLevel.PRIVATE 来将其设置为私有。因为必须设置 final 属性,所以还要将 force 属性设置为 true,这将导致 Lombok 生成的构造函数将它们设置为 null。

还添加了一个 @RequiredArgsConstructor。@Data 隐式地添加了一个必需的有参构造函数,但是当使用 @NoArgsConstructor 时,该构造函数将被删除。显式的 @RequiredArgsConstructor 确保除了私有无参数构造函数外,仍然有一个必需有参构造函数。

现在让我们转到 Taco 类,看看如何将其注解为 JPA 实体。

与 Ingredient 一样,Taco 类现在使用 @Entity 注解,其 id 属性使用 @Id 注解。因为依赖于数据库自动生成 id 值,所以还使用 @GeneratedValue 注解 id 属性,指定自动策略。

要声明 Taco 及其相关 Ingredient 列表之间的关系,可以使用 @ManyToMany 注解 ingredient 属性。一个 Taco 可以有很多 Ingredient,一个 Ingredient 可以是很多 Taco 的一部分。

还有一个新方法 createdAt(),它用 @PrePersist 注解。将使用它将 createdAt 属性设置为保存 Taco 之前的当前日期和时间。最后,让我们将 Order 对象注解为一个实体。下一个程序清单展示了新的 Order 类。

对 Order 的更改与对 Taco 的更改非常相似。但是在类级别有一个新的注解:@Table。这指定订单实体应该持久化到数据库中名为 Taco_Order 的表中。

尽管可以在任何实体上使用这个注解,但它对于 Order 是必需的。没有它,JPA 将默认将实体持久化到一个名为 Order 的表中,但是 Order 在 SQL 中是一个保留字,会导致问题。现在实体已经得到了正确的注解,该编写 repository 了。

最后更新于

这有帮助吗?