Albumに対して複数のMusicを関連付けてみる。
まずはMusicクラスを作成する。
package jp.abc;
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 Music {
@Id
@Column
@GeneratedValue
@NotNull
private long id;
@Column
@NotEmpty
private String title;
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;
}
}
Albumとの関連付けをするために、インスタンス変数を追加して、@ManyToOne のアノテーションで関連を定義する。
package jp.abc;
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 Music {
@Id
@Column
@GeneratedValue
@NotNull
private long id;
@Column
@NotEmpty
private String title;
@ManyToOne
private Album album;
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 Album getAlbum() {
return album;
}
public void setAlbum(Album album) {
this.album = album;
}
}
Album クラスにも Music との関連付けのコードを追加する。
package jp.abc;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
@Entity
public class Album {
@Id
@Column
@GeneratedValue
private long id;
@Column(length = 100, nullable = false)
private String title;
@Column(length = 100, nullable = false)
private String artist;
@OneToMany
private List<Music> musics;
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 getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public List<Music> getMusics() {
return musics;
}
public void setMusics(List<Music> musics) {
this.musics = musics;
}
}
Music クラスをデータベースに保存するためのRepositoryを作成する。
package jp.abc;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MusicRepository extends JpaRepository<Music, Long> {
public Optional<Music> findById(long id);
}
Music用のテンプレートを作成する。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Music</title>
</head>
<body>
<div th:fragment="music">
<h1>Music</h1>
<p>Musicフラグメント</p>
<p th:text="${msg}"></p>
<form action="/music" method="post" th:object="${music}">
<table>
<tr>
<th>タイトル</th>
<td>
<input type="text" name="title" th:value="*{title}" />
<div th:if="${#fields.hasErrors('title')}" th:errors="*{title}"></div>
</td>
</tr>
<tr>
<th>Albumのid</th>
<td>
<input type="text" name="album" th:value="*{album}" />
<div th:if="${#fields.hasErrors('album')}" th:errors="*{album}"></div>
</td>
</tr>
<tr>
<th></th><td><input type="submit" value="登録" /></td>
</tr>
</table>
</form>
<table>
<tr>
<th>ID</th>
<th>アルバム</th>
<th>タイトル</th>
</tr>
<tr th:each="music : ${list}">
<td th:text="${music.id}"></td>
<td th:text="${music.album.title}"></td>
<td th:text="${music.title}"></td>
</tr>
</table>
</div>
</body>
</html>
music.html テンプレートを表示するためのコントローラを作成する。
package jp.abc;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class MusicController {
@Autowired
private MusicRepository repository;
@RequestMapping(value = "/music", method = RequestMethod.GET)
public ModelAndView msg(ModelAndView mav) {
List<Music> list = repository.findAll();
mav.addObject("list", list);
mav.addObject("template", "music");
mav.addObject("fragment", "music");
mav.setViewName("layout");
Music music = new Music();
mav.addObject("music", music);
return mav;
}
}
コントローラでPOSTメソッドを受け付けるようにする。
@RequestMapping(value = "/music", method = RequestMethod.POST)
public ModelAndView post(
@ModelAttribute("music") @Validated Music music,
BindingResult result,
ModelAndView mav) {
if (result.hasErrors()) {
List<Music> list = repository.findAll();
mav.addObject("list", list);
mav.addObject("template", "music");
mav.addObject("fragment", "music");
mav.setViewName("layout");
return mav;
}
repository.saveAndFlush(music);
return new ModelAndView("redirect:/music");
}
トップページでリスト表示している箇所の、アルバムタイトルの部分をリンクにしてみる。
<table>
<tr>
<th>ID</th>
<th>タイトル</th>
<th>アーティスト</th>
<th>操作</th>
</tr>
<tr th:each="album : ${list}">
<td th:text="${album.id}"></td>
<td>
<a th:href="@{'/album/' + ${album.id}}" th:text="${album.title}"></a>
</td>
<td th:text="${album.artist}"></td>
<td>
<a th:href="@{'/edit/' + ${album.id}}">編集</a>
<a th:href="@{'/delete/' + ${album.id}}">削除</a>
</td>
</tr>
</table>
</div>
アルバムのページに遷移するためのコントローラを作成する。
package jp.abc;
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.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class AlbumController {
@Autowired
AlbumRepository repository;
@RequestMapping(value = "/album/{id}", method = RequestMethod.GET)
public ModelAndView index(
@PathVariable long id,
ModelAndView mav) {
Optional<Album> data = repository.findById(id);
Album album = data.get();
mav.addObject("album", album);
mav.addObject("template", "album");
mav.addObject("fragment", "album");
mav.setViewName("layout");
return mav;
}
}
テンプレート album.html を作成する。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Album</title>
</head>
<body>
<div th:fragment="album">
<h1>Album</h1>
<p>Albumフラグメント</p>
<p th:text="${msg}"></p>
<h2 th:text="${album.title}"></h2>
<h3 th:text="${album.artist}"></h3>
<p>収録曲</p>
<ol th:each="music : ${album.musics}">
<li th:text="${music.title}"></li>
</ol>
</div>
</body>
</html>