SpringBootを使用して本棚アプリケーションを作成する。
新規プロジェクトで springスタータープロジェクト を作成して、pom.xml の以下の箇所を修正する。
プロジェクト名: bookshelf
パッケージ: jp.bookshelf
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>jp.bookshelf</groupId> <artifactId>bookshelf</artifactId> <version>0.0.1-SNAPSHOT</version> <name>bookshelf</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
データベースに関する設定
src/main/resources
application.properties
spring.datasource.url=jdbc:hsqldb:file:./db/bookshelf spring.datasource.username=SA spring.datasource.password= spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver spring.jpa.hibernate.ddl-auto=update
src/main/java
/bookshelf/{id} にアクセスしたら、その本棚の内容を表示する。
IndexController.java
package jp.bookshelf; import java.util.List; import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; @Controller public class IndexController { @Autowired private BookshelfRepository repository; @RequestMapping("/") public ModelAndView index(ModelAndView mav) { List<Bookshelf> list = repository.findAll(); mav.setViewName("index"); mav.addObject("list", list); return mav; } @RequestMapping("/new-bookshelf") public ModelAndView shindan2(ModelAndView mav, @RequestParam("name") String name) { Bookshelf bookshelf = new Bookshelf(); bookshelf.setName(name); repository.saveAndFlush(bookshelf); mav.setViewName("bookshelf"); mav.addObject("bookshelf", bookshelf); return mav; } @RequestMapping("/bookshelf/{id}") public ModelAndView bookshelf(ModelAndView mav, @PathVariable long id) { mav.setViewName("bookshelf"); Optional<Bookshelf> data = repository.findById(id); mav.addObject("bookshelf", data.get()); return mav; } }
本棚の名前をリンクにしてそれぞれの本棚に飛べるようにする。
本の一覧へのリンクも追加する。
src/main/resources/templates
index.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>本棚</title> </head> <body> <h1>本棚</h1> <p>本棚のリストを表示します。</p> <ul th:each="bs : ${list}"> <li> <a th:href="@{'/bookshelf/' + ${bs.id}}" th:text="${bs.name}"></a> </li> </ul> <form class="center" action="/new-bookshelf" method="post"> 名前: <input class="w100" type="text" name="name" /> <input type="submit" value="追加" /> </form> <h3><a href="/book">本の一覧</a></h3> </body> </html>
src/main/java
BookController.java
package jp.bookshelf; import java.util.List; import java.util.Optional; 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.PathVariable; 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; @Autowired private BookshelfRepository bookshelfRepository; @RequestMapping(value = "/book", method = RequestMethod.GET) public ModelAndView list(ModelAndView mav) { mav.addObject("book", new Book()); mav.setViewName("books"); List<Book> list = repository.findAll(); List<Bookshelf> bookshelfs = bookshelfRepository.findAll(); mav.addObject("list", list); mav.addObject("bookshelfs", bookshelfs); 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"); } @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; } @RequestMapping(value = "/edit", method = RequestMethod.POST) public ModelAndView update(ModelAndView mav, @ModelAttribute("book") Book book) { repository.saveAndFlush(book); return new ModelAndView("redirect:/book"); } }
src/main/resources/templates
books.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>本のリスト</title> <style type="text/css"> img.book-image { width: 100px; } </style> </head> <body> <h2>本を追加</h2> <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 /> 画像URL: <input type="text" name="image" th:value="*{image}" /> <br /> <input type="submit" value="本を追加" /> </form> <h1>本のリスト</h1> <table> <tr> <th>画像</th><th>タイトル</th><th>著者名</th><th>操作</th><th>本棚</th> </tr> <tr th:each="book : ${list}"> <td><img class="book-image" th:src="${book.image}" /></td> <td th:text="${book.title}"></td> <td th:text="${book.author}"></td> <td> <a th:href="@{'/edit/' + ${book.id}}">修正</a> <a th:href="@{'/delete/' + ${book.id}}">削除</a> </td> <td> 本棚<select name="bookshelf"> <th:block th:each="bookshelf : ${bookshelfs}"> <option value="${bookshelf.id}" th:text="${bookshelf.name}"></option> </th:block> </select>に移動する <p th:if="${book.bookshelf != null}" th:text="${book.bookshelf.name}"> </td> </tr> </table> </body> </html>
books.html に formタグを追加して、指定した本棚への移動をできるようにする。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>本のリスト</title> <style type="text/css"> img.book-image { width: 100px; } </style> </head> <body> <h2>本を追加</h2> <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 /> 画像URL: <input type="text" name="image" th:value="*{image}" /> <br /> <input type="submit" value="本を追加" /> </form> <h1>本のリスト</h1> <table> <tr> <th>画像</th><th>タイトル</th><th>著者名</th><th>操作</th><th>本棚</th> </tr> <tr th:each="book : ${list}"> <td><img class="book-image" th:src="${book.image}" /></td> <td th:text="${book.title}"></td> <td th:text="${book.author}"></td> <td> <a th:href="@{'/edit/' + ${book.id}}">修正</a> <a th:href="@{'/delete/' + ${book.id}}">削除</a> </td> <td> <form action="/push" method="post"> <input type="hidden" name="id" th:value="${book.id}" /> <select name="bookshelf"> <th:block th:each="bookshelf : ${bookshelfs}"> <option th:value="${bookshelf.id}" th:text="${bookshelf.name}"></option> </th:block> </select>に<button>移動</button>する <p th:if="${book.bookshelf != null}" th:text="${book.bookshelf.name}"> </form> </td> </tr> </table> </body> </html>
src/main/java
BookController.java
package jp.bookshelf; import java.util.List; import java.util.Optional; 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.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; @Controller public class BookController { @Autowired private BookRepository repository; @Autowired private BookshelfRepository bookshelfRepository; @RequestMapping(value = "/book", method = RequestMethod.GET) public ModelAndView list(ModelAndView mav) { mav.addObject("book", new Book()); mav.setViewName("books"); List<Book> list = repository.findAll(); List<Bookshelf> bookshelfs = bookshelfRepository.findAll(); mav.addObject("list", list); mav.addObject("bookshelfs", bookshelfs); 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"); } @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; } @RequestMapping(value = "/edit", method = RequestMethod.POST) public ModelAndView update(ModelAndView mav, @ModelAttribute("book") Book book) { repository.saveAndFlush(book); return new ModelAndView("redirect:/book"); } @RequestMapping(value = "/push", method = RequestMethod.POST) public ModelAndView push(ModelAndView mav, @RequestParam("id") long id, @RequestParam("bookshelf") long bookshelfId) { Optional<Book> data = repository.findById(id); Book book = data.get(); Optional<Bookshelf> bs = bookshelfRepository.findById(bookshelfId); Bookshelf bookshelf = bs.get(); bookshelf.addBook(book); bookshelfRepository.saveAndFlush(bookshelf); return new ModelAndView("redirect:/bookshelf/" + bookshelfId); } }
src/main/resources/templates
bookshelf.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>本棚</title> <style type="text/css"> img.book-image { width: 100px; } </style> </head> <body> <h1>本棚 : <span th:text="${bookshelf.name}"></span></h1> <p>この本棚に入っている本のリスト</p> <table> <tr> <th>画像</th><th>タイトル</th><th>著者名</th><th>操作</th> </tr> <tr th:each="book : ${bookshelf.books}"> <td><img class="book-image" th:src="${book.image}" /></td> <td th:text="${book.title}"></td> <td th:text="${book.author}"></td> <td> <a th:href="@{'/edit/' + ${book.id}}">修正</a> <a th:href="@{'/delete/' + ${book.id}}">削除</a> </td> </tr> </table> <a href="/">戻る</a> </body> </html>