6月30日

orderByによるエンティティのソート

getAll() メソッドの中でorderByを指定して、名前で昇順または降順でソートしてみる。

MyDataDaoCriteria.java の getAll() を変更する。

	public List<MyData> getAll() {
		EntityManager manager = factory.createEntityManager();
		List<MyData> list = null;
		CriteriaBuilder builder = manager.getCriteriaBuilder();
		CriteriaQuery<MyData> q = builder.createQuery(MyData.class);
		Root<MyData> root = q.from(MyData.class);
		q.select(root).orderBy(builder.desc(root.get("name")));
		list = (List<MyData>)manager.createQuery(q).getResultList();
		return list;
	}

取得位置と取得個数の指定も可能。

	public List<MyData> getAll() {
		EntityManager manager = factory.createEntityManager();
		List<MyData> list = null;
		CriteriaBuilder builder = manager.getCriteriaBuilder();
		CriteriaQuery<MyData> q = builder.createQuery(MyData.class);
		Root<MyData> root = q.from(MyData.class);
		q.select(root).orderBy(builder.desc(root.get("name")));
		list = (List<MyData>)manager.createQuery(q)
				.setFirstResult(2)
				.setMaxResults(2)
				.getResultList();
		return list;
	}

JPQLではID・名前・メールアドレスから検索できていたので、CriteriaAPIでも同様に検索できるようにする。
find() メソッドを変更する。

	public List<MyData> find(String fstr) {
		EntityManager manager = factory.createEntityManager();
		List<MyData> list = null;
		CriteriaBuilder builder = manager.getCriteriaBuilder();
		CriteriaQuery<MyData> q = builder.createQuery(MyData.class);
		Root<MyData> root = q.from(MyData.class);
		int fid = 0;
		try {
			fid = Integer.parseInt(fstr);
		} catch (NumberFormatException e) {}
		q.select(root).where(
			builder.or(
				builder.equal(root.get("id"), fid),
				builder.like(root.<String>get("name"), "%" + fstr + "%"),
				builder.like(root.<String>get("mail"), "%" + fstr + "%")
				)
			);
		list = (List<MyData>)manager.createQuery(q).getResultList();
		return list;
	}

クリックしたら名前の昇順または降順でソートできるようにする。

まずはJSPにクリックするための矢印を追加する。

		<hr>
		<c:if test="${datalist != null}">
		<table>
			<tr>
				<th>ID</th>
				<th>名前<a href="?sort=a">↓</a>
						<a href="?sort=d">↑</a></th>
			</tr>
			<c:forEach var="obj" items="${datalist}" varStatus="status">
				<tr>
				<td><c:out value="${obj.id}" /></td>
				<td><c:out value="${obj.name}" /></td>
				</tr>
			</c:forEach>
		</table>
		</c:if>

コントローラで引数を受け取れるようにする。
引数なしでも受け付けるようにするために @RequestParam の引数に required = false を追加する。

	@RequestMapping(value = "/mydata", method = RequestMethod.GET)
	public String mydata(@RequestParam(value = "sort", required = false) String s, Model model) {
		model.addAttribute("title");
		model.addAttribute("message", "MyDataのサンプルです。" + s);
		MyData mydata = new MyData();
		model.addAttribute("myData", mydata);

MyDataDao にソート指定できる getAll() を追加し、ソート順を指定するための定数を追加する。

package jp.abc;

import java.io.Serializable;
import java.util.List;

public interface MyDataDao<T> extends Serializable {
	public static final int ASC = 1;
	public static final int DESC = 2;

	public List<T> getAll();
	public List<T> getAll(int sort);
	public T findById(long id);
	public List<T> findByName(String name);
	public void add(T data);
	public void update(T data);
	public void delete(T data);
	public void delete(long id);
	public List<T> find(String param);
}

MyDataDaoImple と MyDataDaoCriteria に、引数付 getAll() を作成する。
引数なしのgetAll() をコピーして貼り付けし、getAll(int sort) に変更すればよい。

public class MyDataDaoCriteria implements MyDataDao<MyData>{
	private static EntityManagerFactory factory =
			Persistence.createEntityManagerFactory("persistenceUnit");

	public List<MyData> getAll() {
		EntityManager manager = factory.createEntityManager();
		List<MyData> list = null;
		CriteriaBuilder builder = manager.getCriteriaBuilder();
		CriteriaQuery<MyData> q = builder.createQuery(MyData.class);
		Root<MyData> root = q.from(MyData.class);
		q.select(root);
		list = (List<MyData>)manager.createQuery(q).getResultList();
		return list;
	}

	public List<MyData> getAll(int sort) {
		EntityManager manager = factory.createEntityManager();
		List<MyData> list = null;
		CriteriaBuilder builder = manager.getCriteriaBuilder();
		CriteriaQuery<MyData> q = builder.createQuery(MyData.class);
		Root<MyData> root = q.from(MyData.class);
		q.select(root);
		list = (List<MyData>)manager.createQuery(q).getResultList();
		return list;
	}

getAll(int)の実装を修正して、ソートできるようにする。

	public List<MyData> getAll(int sort) {
		EntityManager manager = factory.createEntityManager();
		List<MyData> list = null;
		CriteriaBuilder builder = manager.getCriteriaBuilder();
		CriteriaQuery<MyData> q = builder.createQuery(MyData.class);
		Root<MyData> root = q.from(MyData.class);
		if (sort == ASC) {
			q.select(root).orderBy(builder.asc(root.get("name")));
		} else {
			q.select(root).orderBy(builder.desc(root.get("name")));
		}
		list = (List<MyData>)manager.createQuery(q).getResultList();
		return list;
	}

コントローラでは、sortパラメータなしのときは引数なしのgetAll()を、sortパラメータがあるときは、引数ありのgetAll(int)を呼ぶように変更する。

	@RequestMapping(value = "/mydata", method = RequestMethod.GET)
	public String mydata(@RequestParam(value = "sort", required = false) String s, Model model) {
		model.addAttribute("title");
		model.addAttribute("message", "MyDataのサンプルです。" + s);
		MyData mydata = new MyData();
		model.addAttribute("myData", mydata);
		MyDataDao<MyData> dao = new MyDataDaoCriteria();
		List<MyData> list = null;
		if (s == null) {
			list = dao.getAll();
		} else {
			int v = s.equals("a") ? MyDataDao.ASC : MyDataDao.DESC;
			list = dao.getAll(v);
		}
		model.addAttribute("datalist", list);
		return "mydata";
	}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です