7月13日

投稿者: | 2020年7月13日

エラーメッセージを各フィールドに表示する。

<!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;
	}