简体   繁体   English

如何在一对多关系中处理 Thymeleaf 和 Spring 中的 forms?

[英]How to handle forms in Thymeleaf and Spring in one to many relationships?

These are the models below.这些是下面的模型。 I omitted getters and setters for the models.我省略了模型的 getter 和 setter。

Book class预订 class

@Entity
public class Book extends BaseEntity {

private String bookName;
private String bookSubtitle;
private String seriesName;
private String isbnNumber;
private String bookDescription;

@ManyToOne
private Author author;

@ManyToOne
private Publisher publisher;

///// Author class
@Entity
public class Author extends BaseEntity {
     private String authorName;
     private String authorDescription;

     @OneToMany(cascade = CascadeType.ALL, mappedBy = "author", fetch = FetchType.LAZY)
     private Set<Book> books = new HashSet<>(); 

///// Publisher class ///// 发布者 class

@Entity
public class Publisher extends BaseEntity {

private String publisherName;
private String publisherDescription;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "publisher", fetch = FetchType.LAZY)
private Set<Book> books;

protected Publisher() {}

public Publisher(String publisherName, String publisherDescription) {
    this.publisherName = publisherName;
    this.publisherDescription = publisherDescription;
}

// My home.html file. // 我的家.html 文件。

 <form action="#" th:action="@{/api/v1/books}" th:object="${book}" th:method="POST">
            <div class="form-group col-7">
                <label for="bookName" class="col-form-label">Kitap Adi:</label>
                <input th:field="*{bookName}" type="text" class="form-control" id="bookName">
            </div>
            <div class="form-group col-7">
                <label for="subTitle" class="col-form-label">Alt Baslik:</label>
                <input th:field="*{bookSubtitle}" type="text" class="form-control" id="subTitle">
            </div>
            <div class="form-group col-7">
                <label for="seriesName" class="col-form-label">Seri Adi:</label>
                <input th:field="*{seriesName}" type="text" class="form-control" id="seriesName">
            </div>
            <div class="form-group col-7">
                <label for="isbnNumber" class="col-form-label">ISBN:</label>
                <input th:field="*{isbnNumber}" type="text" class="form-control" id="isbnNumber">
            </div>
            <div class="form-group">
                <label for="bookDescription" class="col-form-label">Kitap Aciklamasi:</label>
                <input th:field="*{bookDescription}" type="text" class="form-control" id="bookDescription">
            </div>

            <div class="form-group">
                <label for="exampleFormControlSelect1">Yazar sec</label>
                <select class="form-control" id="exampleFormControlSelect1" th:field="*{author}">
                    <option th:each="aut : ${authors}" th:value="${(aut.getAuthorName())}" th:text="${aut.getAuthorName()}"></option>
                </select>
            </div>

            <div class="form-group">
                <label for="exampleFormControlSelect2">Yayinci sec</label>
                <select class="form-control" id="exampleFormControlSelect2" th:field="*{publisher}">
                    <option th:each="publish : ${publishers}" th:value="${publish.getPublisherName()}" th:text="${publish.getPublisherName()}"></option>
                </select>
            </div>

            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Iptal</button>
                <button type="submit" class="btn btn-primary">Ekle</button>
            </div>
        </form>

This is my controller for the post, creating book.这是我的 controller 的帖子,创建书。

@PostMapping("/books")
public Book createBook(Book book) {
    logger.info(book.toString());
    return bookService.save(book);
}

This is my bookService save() method that does all job.这是我的 bookService save() 方法,可以完成所有工作。 I have created one object from both Author and Publisher and in the form I am looping through them.我已经从 Author 和 Publisher 创建了一个 object,并以循环浏览它们的形式。 So, basically my aim is to get the author and publisher name selected by the user and the book details and map them together.所以,基本上我的目标是让用户选择的作者和出版商名称以及书籍详细信息和 map 一起获得。 However, I have tried lots of things and made changes and also checked the internet still couldn't come up with a solution.但是,我尝试了很多事情并进行了更改,并且还检查了互联网仍然无法提出解决方案。 what is wrong in those code segments?这些代码段有什么问题?

public Book save(Book book) {

    Set<Book> books = new HashSet<>();
    System.out.println(book.getPublisher().getPublisherName());
    System.out.println(book.getAuthor().getAuthorName());

    String authorName = book.getPublisher().getPublisherName();
    String publisherName = book.getAuthor().getAuthorName();
    
    Author author = authorRepository.findAuthorByAuthorName(authorName);
    Publisher publisher = publisherRepository.findByPublisherName(publisherName);

    book.setAuthor(author);
    book.setPublisher(publisher);

    books.add(book);
    
    author.setBooks(books);
    publisher.setBooks(books);

    return bookRepository.save(book);

}

It is better to create a dedicated "Form data" object.最好创建一个专用的“表单数据”object。 In your example, I would do:在您的示例中,我会这样做:

public class CreateBookFormData {
  private String bookName;
  private String bookSubtitle;
  private String seriesName;
  private String isbnNumber;
  private String bookDescription;

  private UUID authorId; // Use whatever type of primary key you are using here
  private UUID publisherId;
}

The controller would change to: controller 将更改为:

@PostMapping("/books")
public Book createBook(CreateBookFormData formData) {
    logger.info(book.toString());
    // You can either pass in the `CreateBookFormData`, or convert it here to a `Book` instance.
    // You will need to convert the `authorId` and `publisherId` to the corresponding entities using their respective repositories or services
    return bookService.save(formData);
}

Note that you cannot use the name of an author or publisher, as there might be duplicates.请注意,您不能使用作者或出版商的姓名,因为可能存在重复。 You need to use the primary key of the entity.您需要使用实体的主键。

In your Thymeleaf template, do something like this:在您的 Thymeleaf 模板中,执行以下操作:

<select th:field="*{authorId}">
  <option th:each="author : ${authors}" th:text="${author.authorName}" th:value="${author.id}">
          </select>

And do the same for the publisher.并为发布者做同样的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM