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");
}