エラーメッセージを各フィールドに表示する。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>linux.html</title>
</head>
<body>
<div th:fragment="mydata">
<h1>MyData</h1>
<p>MyDataフラグメント</p>
<p th:text="${msg}"></p>
<form action="/" method="post" th:object="${mydata}">
<table>
<tr>
<th>名前</th>
<td>
<input type="text" name="name" th:value="*{name}" />
<div th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></div>
</td>
</tr>
<tr>
<th>メール</th>
<td>
<input type="text" name="mail" th:value="*{mail}" />
<div th:if="${#fields.hasErrors('mail')}" th:errors="*{mail}"></div>
</td>
</tr>
<tr>
<th>年齢</th>
<td>
<input type="text" name="age" th:value="*{age}" />
<div th:if="${#fields.hasErrors('age')}" th:errors="*{age}"></div>
</td>
</tr>
<tr>
<th>メモ</th>
<td><textarea rows="5" cols="20" name="memo" th:text="*{memo}"></textarea></td>
</tr>
<tr>
<th></th><td><input type="submit" value="登録" /></td>
</tr>
</table>
</form>
<table>
<tr>
<th>ID</th>
<th>名前</th>
<th>メール</th>
<th>年齢</th>
<th>操作</th>
</tr>
<tr th:each="mydata : ${list}">
<td th:text="${mydata.id}"></td>
<td th:text="${mydata.name}"></td>
<td th:text="${mydata.mail}"></td>
<td th:text="${mydata.age}"></td>
<td>
<a th:href="@{'/edit/' + ${mydata.id}}">編集</a>
<a th:href="@{'/delete/' + ${mydata.id}}">削除</a>
</td>
</tr>
</table>
</div>
<div th:fragment="edit">
<form action="/edit" method="post" th:object="${mydata}">
<input type="hidden" name="id" th:value="*{id}" />
<table>
<tr>
<td>名前</td>
<td><input type="text" name="name" th:value="*{name}" /></td>
</tr>
<tr>
<td>年齢</td>
<td><input type="text" name="age" th:value="*{age}" /></td>
</tr>
<tr>
<td>メール</td>
<td><input type="text" name="mail" th:value="*{mail}" /></td>
</tr>
<tr>
<td>メモ</td>
<td><textarea rows="5" cols="20" name="memo" th:text="*{memo}"></textarea></td>
</tr>
<tr>
<td></td><td><input type="submit" value="送信" /></td>
</tr>
</table>
</form>
</div>
<div th:fragment="delete">
<p>このデータを削除しますか?</p>
<form action="/delete" method="post" th:object="${mydata}">
<input type="hidden" name="id" th:value="*{id}" />
<table>
<tr>
<td>名前</td>
<td th:text="*{name}"></td>
</tr>
<tr>
<td>年齢</td>
<td th:text="*{age}"></td>
</tr>
<tr>
<td>メール</td>
<td th:text="*{mail}"></td>
</tr>
<tr>
<td>メモ</td>
<td><textarea rows="5" cols="20" name="memo" th:text="*{memo}" readonly></textarea></td>
</tr>
<tr>
<td></td><td><input type="submit" value="削除" /></td>
</tr>
</table>
</form>
</div>
</body>
</html>
EntityManagerを使ったクエリを実装する。
DAO(Data Access Object)を用意する。
package jp.abc;
import java.util.List;
public interface MyDataDao {
public List<MyData> getAll();
}
DAOの実装クラスを作成する。
package jp.abc;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
public class MyDataCriteriaDao implements MyDataDao {
private EntityManager entityManager;
public MyDataCriteriaDao() {
super();
}
public MyDataCriteriaDao(EntityManager manager) {
this();
entityManager = manager;
}
@Override
public List<MyData> getAll() {
Query query = entityManager.createQuery("from MyData");
List<MyData> list = query.getResultList();
entityManager.close();
return list;
}
}
コントローラを新しく作成する。
package jp.abc;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
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 MyDataDaoController {
@PersistenceContext
private EntityManager entityManager;
private MyDataCriteriaDao dao = new MyDataCriteriaDao(entityManager);
@RequestMapping(value = "/dao", method = RequestMethod.GET)
public ModelAndView index(ModelAndView mav) {
List<MyData> list = dao.getAll();
mav.addObject("list", list);
mav.addObject("template", "mydata");
mav.addObject("fragment", "mydata");
mav.setViewName("layout");
return mav;
}
}
このままではエラーが発生するので、少し修正を加えて動くようにしたものが以下のコード。
package jp.abc;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
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 MyDataDaoController {
@PersistenceContext
private EntityManager entityManager;
private MyDataCriteriaDao dao;
@PostConstruct
public void init() {
dao = new MyDataCriteriaDao(entityManager);
}
@RequestMapping(value = "/dao", method = RequestMethod.GET)
public ModelAndView index(
@ModelAttribute("mydata") MyData mydata,
ModelAndView mav) {
List<MyData> list = dao.getAll();
mav.addObject("list", list);
mav.addObject("template", "mydata");
mav.addObject("fragment", "mydata");
mav.setViewName("layout");
return mav;
}
}
名前で検索する機能を追加してみる。
まず、HTMLテンプレートにqueryフラグメントを追加する。
<div th:fragment="query">
<p>名前で検索</p>
<form action="/query" method="post">
<input type="text" name="keyword" th:value="${value}" />
<input type="submit" value="検索" />
</form>
<table>
<tr>
<th>ID</th>
<th>名前</th>
<th>メール</th>
<th>年齢</th>
<th>操作</th>
</tr>
<tr th:each="mydata : ${list}">
<td th:text="${mydata.id}"></td>
<td th:text="${mydata.name}"></td>
<td th:text="${mydata.mail}"></td>
<td th:text="${mydata.age}"></td>
<td>
<a th:href="@{'/edit/' + ${mydata.id}}">編集</a>
<a th:href="@{'/delete/' + ${mydata.id}}">削除</a>
</td>
</tr>
</table>
</div>
queryフラグメントを表示するために、コントローラにメソッドを追加する。
@RequestMapping(value = "/query", method = RequestMethod.GET)
public ModelAndView query(
@ModelAttribute("mydata") MyData mydata,
ModelAndView mav) {
List<MyData> list = dao.getAll();
mav.addObject("list", list);
mav.addObject("template", "mydata");
mav.addObject("fragment", "query");
mav.setViewName("layout");
return mav;
}
POSTメソッドを受け付けるメソッドを追加する。
@RequestMapping(value = "/query", method = RequestMethod.POST)
public ModelAndView executeQuery(
@RequestParam("keyword") String keyword,
ModelAndView mav) {
List<MyData> list = dao.find(keyword);
mav.addObject("list", list);
mav.addObject("template", "mydata");
mav.addObject("fragment", "query");
mav.setViewName("layout");
return mav;
}
MyDataCriteriaDaoにfindメソッドを追加する。
public List<MyData> find(String keyword) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<MyData> query = builder.createQuery(MyData.class);
Root<MyData> root = query.from(MyData.class);
query.select(root)
.where(builder.equal(root.get("name"), keyword));
List<MyData> list = entityManager.createQuery(query).getResultList();
return list;
}
文字列の部分一致で検索したい場合は、以下の部分を修正する。
SQLと似たような書き方。
public List<MyData> find(String keyword) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<MyData> query = builder.createQuery(MyData.class);
Root<MyData> root = query.from(MyData.class);
query.select(root)
.where(builder.like(root.get("name"), "%" + keyword + "%"));
List<MyData> list = entityManager.createQuery(query).getResultList();
return list;
}
結果をソートしたい場合は、orderBy()を使用する。
public List<MyData> find(String keyword) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<MyData> query = builder.createQuery(MyData.class);
Root<MyData> root = query.from(MyData.class);
query.select(root)
.where(builder.like(root.get("name"), "%" + keyword + "%"))
.orderBy(builder.asc(root.get("age")));
List<MyData> list = entityManager.createQuery(query).getResultList();
return list;
}