HSQLDBデータベースサーバーを使用する
配布フォルダからhsqldbフォルダを個々のフォルダにコピーする。
hsqldb.bat をダブルクリックすると、データベースサーバーが起動する。
application.properties ファイルの修正
spring.datasource.url=jdbc:hsqldb:hsql://localhost/bookshelf spring.datasource.username=SA spring.datasource.password= spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect spring.jpa.hibernate.ddl-auto=update
本棚アプリに本を追加する
本棚と同様に追加していけばよい。
本棚の時は
Model: Bookshelf
Controller: BookshelfController
View: bookshelf.html
本も本棚と同様に、
Model: Book
Controller: BookController
View: book.html
まずは Book.java を作成する。
package jp.or.jeed; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; @Entity public class Book { @Id @GeneratedValue @Column @NotNull private long id; @Column @NotEmpty private String title; @Column @NotEmpty private String author; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } } 次にコントローラーを作成する。 BookController.java [java] package jp.or.jeed; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView; @Controller public class BookController { @Autowired private BookRepository repository; @RequestMapping(value = "/book", method = RequestMethod.GET) public ModelAndView list(ModelAndView mav) { mav.setViewName("book"); mav.addObject("book", new Book()); List<Book> list = repository.findAll(); mav.addObject("list", list); return mav; } @RequestMapping(value = "/book", method = RequestMethod.POST) public ModelAndView post(ModelAndView mav, @ModelAttribute("book") Book book) { repository.saveAndFlush(book); return new ModelAndView("redirect:/book"); } }
ビューテンプレートとなるHTMLを作成する。
book.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>本リスト</title> </head> <body> <h1>本リスト</h1> <p>本のリストを表示します。</p> <form action="/book" method="post" th:object="${book}"> タイトル: <input type="text" name="title" th:value="*{title}" /><br /> 著者: <input type="text" name="author" th:value="*{author}" /><br /> <input type="submit" value="本を作成" /> </form> <hr /> <table> <tr> <th>ID</th><th>タイトル</th><th>著者</th> </tr> <tr th:each="b : ${list}"> <td th:text="${b.id}"></td> <td th:text="${b.title}"></td> <td th:text="${b.author}"></td> </tr> </table> <a href="/">トップページに戻る</a> </body> </html>
データベースとのやりとりを行うリポジトリを作成する。
BookRepository.java
package jp.or.jeed; import org.springframework.data.jpa.repository.JpaRepository; public interface BookRepository extends JpaRepository<Book, Long> { }
本を本棚に格納する(関連付ける)
本に対しては1個の本棚が関連する。
package jp.or.jeed; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; @Entity public class Book { @Id @GeneratedValue @Column @NotNull private long id; @Column @NotEmpty private String title; @Column @NotEmpty private String author; @ManyToOne private Bookshelf bookshelf; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public Bookshelf getBookshelf() { return bookshelf; } public void setBookshelf(Bookshelf bookshelf) { this.bookshelf = bookshelf; } }
Bookshelf から Book への関連付けも行う。
package jp.or.jeed; import java.util.List; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; @Entity public class Bookshelf { @Id @GeneratedValue @Column @NotNull private long id; @Column @NotEmpty private String name; @OneToMany private List<Book> books; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Book> getBooks() { return books; } public void setBooks(List<Book> books) { this.books = books; } }
本のリストに、本棚の名前も表示する。
book.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>本リスト</title> </head> <body> <h1>本リスト</h1> <p>本のリストを表示します。</p> <form action="/book" method="post" th:object="${book}"> タイトル: <input type="text" name="title" th:value="*{title}" /><br /> 著者: <input type="text" name="author" th:value="*{author}" /><br /> 本棚: <input type="text" name="bookshelf" th:value="*{bookshelf}"/><br /> <input type="submit" value="本を作成" /> </form> <hr /> <table> <tr> <th>ID</th><th>タイトル</th><th>著者</th><th>本棚</th> </tr> <tr th:each="b : ${list}"> <td th:text="${b.id}"></td> <td th:text="${b.title}"></td> <td th:text="${b.author}"></td> <td th:if="${b.bookshelf != null}" th:text="${b.bookshelf.name}"></td> <td th:if="${b.bookshelf == null}" th:text="本棚に入ってません"></td> </tr> </table> <a href="/">トップページに戻る</a> </body> </html>
本を格納する本棚を変更できるようにする。
まずは変更するための画面に飛ばせるようにする。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>本リスト</title> </head> <body> <h1>本リスト</h1> <p>本のリストを表示します。</p> <form action="/book" method="post" th:object="${book}"> タイトル: <input type="text" name="title" th:value="*{title}" /><br /> 著者: <input type="text" name="author" th:value="*{author}" /><br /> 本棚: <input type="text" name="bookshelf" th:value="*{bookshelf}"/><br /> <input type="submit" value="本を作成" /> </form> <hr /> <table> <tr> <th>ID</th><th>タイトル</th><th>著者</th><th>本棚</th><th>修正</th> </tr> <tr th:each="b : ${list}"> <td th:text="${b.id}"></td> <td th:text="${b.title}"></td> <td th:text="${b.author}"></td> <td th:if="${b.bookshelf != null}" th:text="${b.bookshelf.name}"></td> <td th:if="${b.bookshelf == null}" th:text="本棚に入ってません"></td> <td><a th:href="@{'/edit/' + ${b.id}}">編集</a></td> </tr> </table> <a href="/">トップページに戻る</a> </body> </html>
BookController に、編集するためのマッピングを追加する。
@RequestMapping(value = "/edit/{id}", method = RequestMethod.GET) public ModelAndView edit(ModelAndView mav, @PathVariable long id) { mav.setViewName("edit"); Optional<Book> data = repository.findById(id); mav.addObject("book", data.get()); return mav; }
本の編集をするためのHTMLテンプレートを作成する
edit.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>本の編集</title> </head> <body> <h1>本の編集</h1> <p>本のタイトルなどを変更します。</p> <form action="/edit" method="post" th:object="${book}"> タイトル: <input type="text" name="title" th:value="*{title}" /><br /> 著者: <input type="text" name="author" th:value="*{author}" /><br /> 本棚: <input type="text" name="bookshelf" th:value="*{bookshelf}"/><br /> <input type="submit" value="本を編集" /> </form> <a href="/">トップページに戻る</a> </body> </html>
本棚のところにきちんと値を表示するために、HTMLを変更する。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>本の編集</title> </head> <body> <h1>本の編集</h1> <p>本のタイトルなどを変更します。</p> <form action="/edit" method="post" th:object="${book}"> <input type="hidden" name="id" th:value="*{id}" /> <table> <tr> <td>タイトル</td> <td><input type="text" name="title" th:value="*{title}" /></td> </tr> <tr> <td>著者</td> <td><input type="text" name="author" th:value="*{author}" /></td> </tr> <tr> <td>本棚のID</td> <td th:if="*{bookshelf != null}"><input type="text" name="bookshelf" th:value="*{bookshelf.id}"/></td> <td th:if="*{bookshelf == null}"><input type="text" name="bookshelf" value=""/></td> </tr> </table> <input type="submit" value="本を編集" /> </form> <a href="/">トップページに戻る</a> </body> </html>
編集した本のデータを受け取ってデータベースを更新する。
@RequestMapping(value = "/edit", method = RequestMethod.POST) public ModelAndView update(ModelAndView mav, @ModelAttribute("book") Book book) { repository.saveAndFlush(book); return new ModelAndView("redirect:/book"); }