Java Spring引导REST api,在外键上传递id而不是整个对象

Java Spring引导REST api,在外键上传递id而不是整个对象,java,spring,rest,api,spring-boot,Java,Spring,Rest,Api,Spring Boot,我正在尝试用Spring boot应用程序为web和移动应用程序构建RESTAPI。在我的应用程序中,我有多个外键,我只想传递对象的id,而不是整个对象。见下面的例子 模型书 // imports @Entity public class Book { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String title; pr

我正在尝试用Spring boot应用程序为web和移动应用程序构建RESTAPI。在我的应用程序中,我有多个外键,我只想传递对象的id,而不是整个对象。见下面的例子

模型书

// imports

@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String title;
    private String isbn;

    @ManyToOne
    @JoinColumn(name = "category_id", updatable = false)
    private BookCategory bookCategory;

    public Book() {
    }

    public Book(Integer id, String title, String isbn, BookCategory bookCategory) {
        this.id = id;
        this.title = title;
        this.isbn = isbn;
        this.bookCategory = bookCategory;
    }

    // getters and setters
}
车型类别

// imports

@Entity
public class BookCategory {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    @OneToMany(mappedBy = "bookCategory", cascade = CascadeType.ALL)
    private List<Book> books;

    public BookCategory() {
    }

    public BookCategory(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    // getters and setters
}
// imports

public interface BookRepository extends PagingAndSortingRepository<Book, Integer> {
}
图书存储库

// imports

@Entity
public class BookCategory {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    @OneToMany(mappedBy = "bookCategory", cascade = CascadeType.ALL)
    private List<Book> books;

    public BookCategory() {
    }

    public BookCategory(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    // getters and setters
}
// imports

public interface BookRepository extends PagingAndSortingRepository<Book, Integer> {
}
回应

{
    "title": "Tirant lo blanc",
    "isbn": "9788475841199",
    "bookCategory": null
}
我也尝试将其作为对象发送,但结果为空

{
    "title": "Tirant lo blanc",
    "isbn": "9788475841199",
    "category_id": {
        "id": 4
    }
}

如何发送类别id以正确地将书籍存储在数据库中?改为发送整个类别对象更好吗?我也试过了,但数据库中的响应和存储的图书始终为空。

有一个非常简单的解决方案。在一个好的RESTAPI设计中,您不允许API用户使用数据库实体进行操作。相反,您引入的DTO将在响应中返回和/或作为消息体接收。在这种情况下,您拥有所有的控制权—您不会公开太多的数据结构。为了实现这一点,您应该首先创建DTO,然后编写DTO和数据库实体之间的映射—这会有所帮助

您的问题有一个非常简单的解决方案。在一个好的RESTAPI设计中,您不允许API用户使用数据库实体进行操作。相反,您引入的DTO将在响应中返回和/或作为消息体接收。在这种情况下,您拥有所有的控制权—您不会公开太多的数据结构。为了实现这一点,您应该首先创建DTO,然后编写DTO和数据库实体之间的映射—这会有所帮助

如果您只想传递对象的id,请将getters设置为您希望它返回的值

例如:

// imports

@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String title;
    private String isbn;

    @ManyToOne
    @JoinColumn(name = "category_id", updatable = false)
    private BookCategory bookCategory;

    public Book() {
    }

    public Book(Integer id, String title, String isbn, BookCategory bookCategory) {
        this.id = id;
        this.title = title;
        this.isbn = isbn;
        this.bookCategory = bookCategory;
    }

   // getters
   public Integer getBookCategory() {
        return bookCategory.getId();
   }
}

如果您只想传递对象的id,请将getters设置为您希望它返回的值

例如:

// imports

@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String title;
    private String isbn;

    @ManyToOne
    @JoinColumn(name = "category_id", updatable = false)
    private BookCategory bookCategory;

    public Book() {
    }

    public Book(Integer id, String title, String isbn, BookCategory bookCategory) {
        this.id = id;
        this.title = title;
        this.isbn = isbn;
        this.bookCategory = bookCategory;
    }

   // getters
   public Integer getBookCategory() {
        return bookCategory.getId();
   }
}

图书没有属性
类别id
。然而,它确实有一个属性
bookCategory
,没错,
bookCategory
是对象,但是Spring在数据库中存储了一个名为
category\u id
的列,该列的id是属于某本书的类别。是的,我显然可以看到。JSON绑定在Java属性名称上无效。Book没有属性
类别id
。然而,它确实有一个属性
bookCategory
,没错,
bookCategory
是对象,但是Spring在数据库中存储了一个名为
category\u id
的列,该列的id是属于某本书的类别。是的,我显然可以看到。JSON绑定在Java属性名上是无效的。很抱歉,这不是答案,而是意见问题。据我所知,这被认为是最佳实践,@AlanHay它对我的项目有效,因此对我来说是一个公认的答案。此外,正如Ilia Ilin所说,这被认为是最佳实践。因此,您要做的是所有这些,而不是像我上面详细介绍的那样正确地命名属性。祝你好运对不起,这不是答案,而是意见问题。据我所知,这被认为是最佳实践,@AlanHay它对我的项目有效,因此对我来说是一个公认的答案。此外,正如Ilia Ilin所说,这被认为是最佳实践。因此,您要做的是所有这些,而不是像我上面详细介绍的那样正确地命名属性。祝你好运