Spring 关系中的数据休息和实体 ID

Spring Data Rest and entities' IDs in relationships

我正在开发基于 Spring Data Rest 的 Spring 引导服务,其数据模型与教程中的相似: https://www.baeldung.com/spring-data-rest-relationships

(在定义实体时,我使用了 Lombok 注释):

@Data
@NoArgsConstructor
@Entity
@Table(name = "cale")
public class Book {

    @Id
    @GeneratedValue
    private long id;

    @Column(nullable=false)
    private String title;

    @ManyToOne
    private Library library;

}


@Data
@NoArgsConstructor
@Entity
@Table(name = "library")
public class Library {


    @Id
    @GeneratedValue
    private long id;
    
    //...


}

调用端点 /books 我得到以下结果 json:

{
      "_embedded": {
        "books": [
          {
            "id": 22,
            "title": "The title of the book",
            "_links": {
              "self": {
                "href": "http://192.168.33.20:8080/books/22"
              },
              "book": {
                "href": "http://192.168.33.20:8080/books/22"
              },
              "library": {
                "href": "http://192.168.33.20:8080/books/22/library"
              }
            }
          },
          .
          .
          .

在 HAL 风格中,对链接到给定书籍的库的唯一引用是通过 URL,例如 http://192.168.33.20:8080/books/22/library

为了获取与第 22 本书关联的图书馆的 ID,我必须对 URL 执行第二次 GET 调用,这在许多情况下效率很低。

此外,这使得很难实现像“获取所有与 id 为 101 的图书馆关联的图书”这样的查询。

有没有办法让 Spring Data Rest 也将关联实体的 ID 包含到返回的 json 中?类似于:

{
      "_embedded": {
        "books": [
          {
            "id": 22,
            "title": "The title of the book",
            "library_id": 101, 
            "_links": {
            .
            .
            .
            }
          },
          .
          .

您可以创建投影并在默认情况下将其与摘录一起使用。

定义投影:

@Projection(
  name = "customBook", 
  types = { Book.class }) 
public interface CustomBook {
 
    @Value("#{target.id}")
    long getId(); 
    
    String getTitle();
    
    @Value("#{target.getLibrary().getId()}")
    int getLibraryId();
}

然后调用:

http://192.168.33.20:8080/books/22?projection=customBook

要默认使用此投影,请配置您的存储库:

@RepositoryRestResource(excerptProjection = CustomBook.class)
public interface BookRepository extends CrudRepository<Book, Long> {}