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>