如何在Spring MVC中提交ManyToMany属性

时间:2017-05-07 20:26:34

标签: java html spring-mvc thymeleaf

背景

我正在使用Spring Boot(带有Thymeleaf的Spring MVC)创建一个非常简单的图书数据库。一本书可以有多个作者,作者可以写几本书,所以我在Book类中创建了一个@ManyToMany引用。

Book.java

@Entity
@Table(name = "book")
public class Book {

    @Id
    @GeneratedValue()
    private Long id;

    private String title;

    @ManyToMany
    @JoinTable(name = "book_author", joinColumns = @JoinColumn(name = "author_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "book_id", referencedColumnName = "id"))
    private List<Author> authors;
...

Author.java

@Entity
@Table(name="author")
public class Author {

    @Id
    @GeneratedValue()
    private Long id;

    private String name;

    @JsonBackReference
    @ManyToMany(mappedBy="authors")
    private List<Book> books;
...

当我自己插入SQL值时,这可以正常工作。

控制器

我有一个@PostMapping,它将收到已编辑的表格。

@GetMapping("/books/{bookId}/edit")
public String editBookForm(@PathVariable(value="bookId") long id, Model model){
    Book book = bookRepository.findOne(id);
    List<Author> authors = new LinkedList<>();
    for ( Author author : authorRepository.findAll())
        authors.add(author);

    model.addAttribute("book", book);
    model.addAttribute("authors", authors);
    return "bookedit";
}


@PostMapping("/books/{bookId}/edit")
public String editBookSubmit(@PathVariable(value="bookId") long id, @ModelAttribute Book book){
    bookRepository.save(book);
    return "redirect:/books/" + id;
}

这是我的表单代码:

<form action="#" th:action="@{/books/{id}/edit(id=${book.id})}" th:object="${book}" method="post">
    <input type="hidden" th:field="*{id}" th:value="${book.id}"/>
    <div class="form-group">
        <label for="title">Book title:</label>
        <input type="text" class="form-control" id="title" th:field="*{title}" th:value="${book.title}"/>
    </div>

    <div class="form-group">
        <label for="author">Authors</label>
        <input list="author"/>

        <datalist id="author">
            <option th:each="author : ${authors}" th:value="${author.name}"></option>
        </datalist>
    </div>
    <input type="submit" class="btn btn-default" value="Save"/>
</form>

我现在有两个问题:

  1. 如何传递多位作者?我想过用Javascript多次复制<input list="author"/>(用户可以点击一个名为“添加另一个作者”的按钮,然后整个字段将被复制)。但是我怎么能在控制器中解析呢?那么我如何命名输入列表呢?

  2. 我可以在datalist中显示作者的姓名,但之后我会将作者的名称返回给控制器,而不是其主键。如果两位作者的名字相同,我该如何区分呢?可见“可见价值”和“实际价值”之间有区别吗?将来,如果是这样的话,我想在作者姓名之后加上一些解释性的话(例如“John Doe(美国作家,1900-1980)”,“John Doe(英国作家,1950-2000))。”但是这将不是该字段的

  3. 感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

好的,这并不困难。我的主要问题是我不知道我可以在<option></option>标签之间写出显示的值。

当为属性传递id时,数据绑定会自动检测其他模型。因此<option value="1">Example book</option>之类的内容会被Spring自动绑定。

多次使用name字段<select>也可以使用数组。