9月28日

チームごとの決定事項

  • グループA
    • チーム名:つぶやき6ヶ
    • リーダー:新納
    • Webアプリ:Twitter
    • Webアプリ名:Digtter
  • グループB
    • チーム名:harunoumi
    • リーダー:芳賀
    • Webアプリ:匿名掲示板
    • Webアプリ名:はがちゃんねる(HGCH)
  • グループC
    • チーム名:kentomori
    • リーダー:森
    • Webアプリ:スケジュール管理
    • Webアプリ名:スケジュール管理
  • グループD
    • チーム名:SESオールスターズ
    • リーダー:篠原
    • Webアプリ:checkpad
    • Webアプリ名:checkpad
  • グループE
    • チーム名:歪みねぇやぴ軍団
    • リーダー:江藤
    • Webアプリ:Twitter
    • Webアプリ名:本格的♂TEITTER

課題の取り扱い

課題は誰でも作れる。
課題を作るときに、担当者を割り当てる。

  1. 課題を作成する(未対応)
  2. 課題に取り掛かる前に「処理中」に変更する
  3. 課題を済ませたら「処理済」に変更する
  4. 「処理済」の課題を他のメンバーに確認してもらう
  5. 確認OKなら、コミットしてプッシュする
  6. 確認したメンバーが「完了」に変更する

リーダーは課題「ロバストネス図を作成する」を追加する。
他のメンバーは課題「クローンする」を作成する。

9月25日

Backlogを使用したチーム開発

決めること

  • チーム名
  • リーダー
  • 作成するWebアプリ
  • Webアプリ名

Webアプリの例

  • 匿名掲示板
  • Twitter
  • LINE
  • SNS
  • Wiki
  • その他

チームリーダーが以下の作業を実施。

  1. Backlog にアクセス。
  2. 「プラント価格はこちら」をクリック。
  3. 右下の「1プロジェクト、10人までのフリープランはこちら」をクリック。
  4. 必要事項を入力してスペースを作成。
  5. 「ユーザーの追加」からチーム全員を招待する。
  6. ユーザーID:satoshis、メールアドレス:satoshis@gmail.com も招待。
  7. プロジェクトを作成し、プロジェクトにメンバーを追加する。
  1. グループA
  2. https://diguhaga.backlog.jp/

  3. グループB
  4. https://harunoumi.backlog.jp/

  5. グループC
  6. https://kentomori.backlog.jp/

  7. グループD
  8. https://ukshhm.backlog.jp/

  9. グループE
  10. https://yapy.backlog.jp/

9月18日

エンティティの連携

MyDataController に POST メソッドのためのメソッドを追加する。

MyDataController.java

	@RequestMapping(value = "/msg", method = RequestMethod.POST)
	public String msgform(@Valid @ModelAttribute MsgData msgdata, Errors result, Model model) {
		System.out.println("msgform: " + msgdata.getMydata());
		if (result.hasErrors()) {
			model.addAttribute("title", "MsgData [Error]");
			model.addAttribute("message", "値が間違っています");
			return "msgdata";
		}
		MsgDataDao<MsgData> dao = new MsgDataDaoImpl();
		dao.add(msgdata);
		return "redirect:/msg";
	}

この変更でクエリ送信はできるようになるが、エラーが表示される。
java.lang.String を jp.abc.MyData に変換できないというエラー。

この対策のため、テキストp.357からのコードを追加する。
まず新規で MyDataPropertyEditor クラスを作成する。

MyDataPropertyEditor.java

package jp.abc;

import java.beans.PropertyEditorSupport;

public class MyDataPropertyEditor extends PropertyEditorSupport {
	public String getAsText() {
		MyData value = (MyData)getValue();
		System.out.println("getAsText: " + value);
		if (value == null) {
			return "";
		} else {
			return "" + value.getId();
		}
	}

	public void setAsText(String value) {
		MyDataDao<MyData> dao = new MyDataDaoImpl();
		MyData mydata = dao.findById(Long.parseLong(value));
		System.out.println("setAsText: " + mydata);
		setValue(mydata);
	}
}

Controller で、作成した PropertyEditor を利用できるように設定する。
MyDataController の先頭に以下のメソッドを追加する。

MyDataController.java

	@InitBinder
	protected void initBinder(HttpServletRequest req,
			ServletRequestDataBinder binder) throws Exception {
		binder.registerCustomEditor(MyData.class, new MyDataPropertyEditor());
	}

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.springframework.samples.service.service</groupId>
  <artifactId>MyData</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

    <properties>

		<!-- Generic properties -->
		<java.version>1.6</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

		<!-- Web -->
		<jsp.version>2.2</jsp.version>
		<jstl.version>1.2</jstl.version>
		<servlet.version>2.5</servlet.version>


		<!-- Spring -->
		<spring-framework.version>3.2.3.RELEASE</spring-framework.version>

		<!-- Hibernate / JPA -->
		<hibernate.version>4.2.1.Final</hibernate.version>

		<!-- Logging -->
		<logback.version>1.0.13</logback.version>
		<slf4j.version>1.7.5</slf4j.version>

		<!-- Test -->
		<junit.version>4.11</junit.version>

	</properties>

	<dependencies>

		<!-- Spring MVC -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>

		<!-- Other Web dependencies -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>${jstl.version}</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>${servlet.version}</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>${jsp.version}</version>
			<scope>provided</scope>
		</dependency>

		<!-- Spring and Transactions -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>

		<!-- Logging with SLF4J & LogBack -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j.version}</version>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>${logback.version}</version>
			<scope>runtime</scope>
		</dependency>

		<!-- Hibernate -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>${hibernate.version}</version>
		</dependency>


		<!-- Test Artifacts -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring-framework.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.1</version>
		</dependency>

		<dependency>
			<groupId>org.hsqldb</groupId>
			<artifactId>hsqldb</artifactId>
			<version>2.3.2</version>
		</dependency>

		<dependency>
			<groupId>javax.transaction</groupId>
			<artifactId>jta</artifactId>
			<version>1.1</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>3.2.4.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>3.2.4.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-jpa</artifactId>
			<version>1.3.4.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.4</version>
			<exclusions>
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				</exclusion>
				<exclusion>
					<groupId>xml-apis</groupId>
					<artifactId>xml-apis</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
			<version>1.1.0.Final</version>
		</dependency>

		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>5.0.1.Final</version>
		</dependency>

	</dependencies>
</project>

9月14日

Criteria API による検索

Criteria API は3つのクラスを組み合わせて利用する。

  • CriteriaBuilder
  • CriteriaQUery
  • Root

テキストでは MyDataDaoImpl を書き換えているが、ここでは新しく実装クラスを作成する。
クラス名を MyDataDaoCriteria とし、Criteria API による実装であることを、クラス名で示す。

新規クラスを作成するときにインタフェース MyDataDao を追加する。総称型 T は、MyData に変更する。
実装されていないメソッドの追加をして、メソッドを生成してもらう。

MyDataDaoCriteria.java

package jp.abc;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

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> query = builder.createQuery(MyData.class);
		Root<MyData> root = query.from(MyData.class);
		query.select(root);
		list = manager.createQuery(query).getResultList();
		return list;
	}

	public MyData findById(long id) {
		// TODO 自動生成されたメソッド・スタブ
		return null;
	}

	public MyData findByName(String name) {
		// TODO 自動生成されたメソッド・スタブ
		return null;
	}

	public List<MyData> find(String s) {
		// TODO 自動生成されたメソッド・スタブ
		return null;
	}

	public void add(MyData data) {
		// TODO 自動生成されたメソッド・スタブ

	}

	public void update(MyData data) {
		// TODO 自動生成されたメソッド・スタブ

	}

	public void delete(MyData data) {
		// TODO 自動生成されたメソッド・スタブ

	}

	public void delete(long id) {
		// TODO 自動生成されたメソッド・スタブ

	}

}

MyDataControllerの変更

MyDataDao に、MyDataDaoCriteria のインスタンスを設定する。

	@RequestMapping(value = "/mydata", method = RequestMethod.GET)
	public String mydata(Model model) {
		model.addAttribute("title", "MyData");
		model.addAttribute("message", "データを入力してください");
		MyData mydata = new MyData();
		model.addAttribute("myData", mydata);
		MyDataDao<MyData> dao = new MyDataDaoCriteria();
		List<MyData> list = dao.getAll();
		model.addAttribute("datalist", list);
		return "mydata";
	}

クエリの実装

MyDataController の find() メソッドで Criteria API を使用する。

MyDataController.java

	@RequestMapping(value = "/find", method = RequestMethod.GET)
	public String find(Model model) {
		model.addAttribute("title", "MyData");
		model.addAttribute("message", "検索のサンプルです");
		MyDataDao<MyData> dao = new MyDataDaoCriteria();
		List<MyData> list = dao.getAll();
		model.addAttribute("datalist", list);
		return "find";
	}

	@RequestMapping(value = "/find", method = RequestMethod.POST)
	public String search(@RequestParam(value = "fstr")String s, Model model) {
		model.addAttribute("title", "MyData");
		model.addAttribute("message", "「" + s + "」の検索結果");
		MyDataDao<MyData> dao = new MyDataDaoCriteria();
		List<MyData> list = dao.find(s);
		model.addAttribute("datalist", list);
		return "find";
	}

MyDataDaoCriteria の find() を実装する。

MyDataDaoCriteria.java

	public List<MyData> find(String s) {
		EntityManager manager = factory.createEntityManager();
		List<MyData> list = null;
		CriteriaBuilder builder = manager.getCriteriaBuilder();
		CriteriaQuery<MyData> query = builder.createQuery(MyData.class);
		Root<MyData> root = query.from(MyData.class);
		List<Predicate> preds = new ArrayList<Predicate>();
		if (s != null) {
			preds.add(builder.like(root.<String>get("name"), "%" + s + "%"));
		}
		query.where(builder.and(preds.toArray(new Predicate[0])));
		query.select(root);
		list = manager.createQuery(query).getResultList();
		return list;
	}

さらに、id と mail でも検索できるようにする。

MyDataDaoCriteria.java

	public List<MyData> find(String s) {
		EntityManager manager = factory.createEntityManager();
		List<MyData> list = null;
		CriteriaBuilder builder = manager.getCriteriaBuilder();
		CriteriaQuery<MyData> query = builder.createQuery(MyData.class);
		Root<MyData> root = query.from(MyData.class);
		List<Predicate> preds = new ArrayList<Predicate>();
		if (s != null) {
			try {
				long id = Long.parseLong(s);
				preds.add(builder.equal(root.get("id"), id));
			} catch (NumberFormatException e) {}
			preds.add(builder.like(root.<String>get("name"), "%" + s + "%"));
			preds.add(builder.like(root.<String>get("mail"), s + "@%"));
		}
		query.where(builder.or(preds.toArray(new Predicate[0])));
		query.select(root);
		list = manager.createQuery(query).getResultList();
		return list;
	}

エンティティの連携

1対多のオブジェクト構造を持つエンティティに対して、永続化の実装を追加する。
ここでは、MsgData クラスを追加し、MyData が複数の MsgData 要素を保持できるようにする。

まず MsgData クラスを作成する。

MsgData.java

package jp.abc;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.validation.constraints.NotNull;

import org.hibernate.validator.constraints.NotEmpty;

@Entity
public class MsgData {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@NotNull
	private long id;

	private String title;

	@NotEmpty
	private String message;

	@ManyToOne
	private MyData mydata;

	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 getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public MyData getMydata() {
		return mydata;
	}

	public void setMydata(MyData mydata) {
		this.mydata = mydata;
	}
}

MyData が複数の MsgData を保持できるようにする。

MyData.java

package jp.abc;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.validation.constraints.Size;

@Entity
public class MyData {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private long id;

	@Size(min = 1)
	@Column(length = 50, nullable = false)
	private String name;

	@Column(length = 200, nullable = true)
	private String mail;

	@Column(nullable = true)
	private Integer age;

	@Column(nullable = true)
	private String memo;

	@OneToMany(cascade = CascadeType.ALL)
	private List<MsgData> msgdatas;

	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 String getMail() {
		return mail;
	}

	public void setMail(String mail) {
		this.mail = mail;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public String getMemo() {
		return memo;
	}

	public void setMemo(String memo) {
		this.memo = memo;
	}

	public List<MsgData> getMsgdatas() {
		return msgdatas;
	}

	public void setMsgdatas(List<MsgData> msgdatas) {
		this.msgdatas = msgdatas;
	}
}

MsgDataDao の用意

MsgDataDao.java

package jp.abc;

import java.util.List;

public interface MsgDataDao<T> {
	public List<T> getAll();
	public T findById(long id);
	public void add(T data);
	public void update(T data);
	public void delete(T data);
	public void delete(long id);
}

MsgDataDaoの実装クラスを作成する。

MsgDataDaoImpl.java

package jp.abc;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;

public class MsgDataDaoImpl implements MsgDataDao<MsgData> {
	private static EntityManagerFactory factory =
			Persistence.createEntityManagerFactory("persistenceUnit");

	public List<MsgData> getAll() {
		EntityManager manager = factory.createEntityManager();
		Query query = manager.createQuery("from MsgData");
		List<MsgData> list = query.getResultList();
		manager.close();
		return list;
	}

	public MsgData findById(long id) {
		EntityManager manager = factory.createEntityManager();
		return (MsgData)manager.createQuery("from MsgData where id = " + id).getSingleResult();
	}

	public void add(MsgData data) {
		EntityManager manager = factory.createEntityManager();
		EntityTransaction tx = manager.getTransaction();
		tx.begin();
		manager.persist(data);
		tx.commit();
		manager.close();
	}

	public void update(MsgData data) {
		EntityManager manager = factory.createEntityManager();
		EntityTransaction tx = manager.getTransaction();
		tx.begin();
		manager.merge(data);
		tx.commit();
		manager.close();
	}

	public void delete(MsgData data) {
		EntityManager manager = factory.createEntityManager();
		EntityTransaction tx = manager.getTransaction();
		tx.begin();
		MsgData entity = manager.merge(data);
		manager.remove(entity);
		tx.commit();
		manager.close();
	}

	public void delete(long id) {
		delete(findById(id));
	}

}

ビューテンプレートの作成

src/main/webapp/WEB-INF/view の中に、JSPファイル msgdata.jsp を新規作成する。

msgdata.jsp

<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>${title}</title>
</head>
<body>
	<h1>${title}</h1>
	<p>${message}</p>
	<table>
	<form:form modelAttribute="msgData">
		<form:errors path="*" />
		<form:hidden path="id"/>
		<tr>
			<td><form:label path="title">タイトル</form:label></td>
			<td><form:input path="title" size="20" /></td>
		</tr>
		<tr>
			<td><form:label path="message">メッセージ</form:label></td>
			<td><form:textarea path="message" cols="20" rows="5" /></td>
		</tr>
		<tr>
			<td><form:label path="mydata">MYDATA_ID</form:label></td>
			<td><form:input path="mydata" size="20" /></td>
		</tr>
		<tr><td></td><td><input type="submit"></td></tr>
	</form:form>
	</table>
	<hr />
	<c:if test="${datalist != null}">
		<table border="1">
			<tr><th>ID</th><th>投稿者</th></tr>
			<c:forEach var="obj" items="${datalist}" varStatus="status">
				<tr>
					<td>${obj.id}</td>
					<td>${obj.mydata.name}</td>
					<td>${obj.title}</td>
					<td>${obj.message}</td>
				</tr>
			</c:forEach>
		</table>
	</c:if>
</body>
</html>

MyDataContoller に、新しいマッピングを追加する。

MyDataController.java

	@RequestMapping(value = "/msg", method = RequestMethod.GET)
	public String msg(Model model) {
		model.addAttribute("title", "MsgData");
		model.addAttribute("message", "MsgDataのサンプル");
		MsgData msgdata = new MsgData();
		model.addAttribute("msgData", msgdata);
		MsgDataDao<MsgData> dao = new MsgDataDaoImpl();
		List<MsgData> list = dao.getAll();
		model.addAttribute("datalist", list);
		return "msgdata";
	}

9月11日

CRUDの実装

エンティティの削除

エンティティを削除するには、remove を使用するが、その前に merge する必要がある。(テキストp.297)

MyDataDaoImpl.java

	public void delete(MyData data) {
		EntityManager manager = factory.createEntityManager();
		EntityTransaction tx = manager.getTransaction();
		tx.begin();
		MyData entity = manager.merge(data);
		manager.remove(entity);
		tx.commit();
		manager.close();
	}

	public void delete(long id) {
		delete(findById(id));
	}

データベースマネージャからSQLをダイレクトに実行する方法

別のアプリDatabaseManagerを使用することで、SQLを実行できる。

  1. 以下のファイルをローカルにコピーする。
    \\KGAKUSEI1\share\澤田\hsqldb-2.3.2.zip
  2. C:\Users\se3\db の下に解凍する。
  3. コマンドプロンプトを起動。
  4. 以下のコマンドを実行する。
    > cd C:\Users\se3\db\hsqldb-2.3.2\hsqldb
    > java -cp lib/hsqldb.jar org.hsqldb.util.DatabaseManager
    

hsqldb

spring12

hsqldbmanager

JSPに編集と削除のリンクを追加する

mydata.jsp のテーブル部分に、編集と削除のリンクをanchorタグで追加する。

mydata.jsp

	<c:if test="${datalist != null}">
		<table border="1">
			<tr><th>ID</th><th>名前</th></tr>
			<c:forEach var="obj" items="${datalist}" varStatus="status">
				<tr>
					<td>${obj.id}</td>
					<td>${obj.name}</td>
					<td><a href="/MyData/update?id=${obj.id}">編集</a></td>
					<td><a href="/MyData/delete?id=${obj.id}">削除</a></td>
				</tr>
			</c:forEach>
		</table>
	</c:if>

JPQLを活用する

MyDataアプリケーションで検索機能を追加する。

find.jspの作成

find.jsp

<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>${title}</title>
</head>
<body>
	<h1>${title}</h1>
	<p>${message}</p>

	<table>
	<form action="/MyData/find" method="post">
		<tr>
			<td>FIND:</td>
			<td><input type="text" name="fstr" size="20" /></td>
		</tr>
		<tr>
			<td></td><td><input type="submit" /></td>
		</tr>
	</form>
	</table>

	<hr />
	<c:if test="${datalist != null}">
		<table border="1">
			<tr><th>ID</th><th>名前</th></tr>
			<c:forEach var="obj" items="${datalist}" varStatus="status">
				<tr>
					<td>${obj.id}</td>
					<td>${obj.name}</td>
				</tr>
			</c:forEach>
		</table>
	</c:if>
</body>
</html>

コントローラの追加

MyDataControllerに検索用メソッドを追加する。

MyDataController.java

	@RequestMapping(value = "/find", method = RequestMethod.GET)
	public String find(Model model) {
		model.addAttribute("title", "MyData");
		model.addAttribute("message", "検索のサンプルです");
		MyDataDao<MyData> dao = new MyDataDaoImpl();
		List<MyData> list = dao.getAll();
		model.addAttribute("datalist", list);
		return "find";
	}

	@RequestMapping(value = "/find", method = RequestMethod.POST)
	public String search(@RequestParam(value = "fstr")String s, Model model) {
		model.addAttribute("title", "MyData");
		model.addAttribute("message", "「" + s + "」の検索結果");
		MyDataDao<MyData> dao = new MyDataDaoImpl();
		List<MyData> list = dao.find(s);
		model.addAttribute("datalist", list);
		return "find";
	}

DAOにfindメソッドを追加する

MyDataDao.java

package jp.abc;

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

public interface MyDataDao <T> extends Serializable {
	public List<T> getAll();
	public T findById(long id);
	public T findByName(String name);
	public List<T> find(String s);
	public void add(T data);
	public void update(T data);
	public void delete(T data);
	public void delete(long id);
}

MyDataDaoImpl.java

	public List<MyData> find(String s) {
		EntityManager manager = factory.createEntityManager();
		List<MyData> list = null;
		String qs = "from MyData where id = :fstr";
		Query query = manager.createQuery(qs).setParameter("fstr", Long.parseLong(s));
		list = query.getResultList();
		manager.close();
		return list;
	}

9月7日

CRUD

CRUDとは?

CRUD(クラッド)とは、ほとんど全てのコンピュータソフトウェアが持つ永続性[1]の4つの基本機能のイニシャルを並べた用語。その4つとは、Create(生成)、Read(読み取り)、Update(更新)、Delete(削除)である。ユーザインタフェースが備えるべき機能(情報の参照/検索/更新)を指す用語としても使われる。
https://ja.wikipedia.org/wiki/CRUD

現状では、CreateとReadしかないので、UpdateとDeleteを追加していく。

MyDataDao にメソッドを追加する。

MyDataDao.java

package jp.abc;

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

public interface MyDataDao <T> extends Serializable {
	public List<T> getAll();
	public T findById(long id);
	public T findByName(String name);
	public void add(T data);
	public void update(T data);
	public void delete(long id);
}

MyDataDao.java を保存すると MyDataDaoImple.java がコンパイルエラーになる。
必要なメソッドを追加する。

MyDataDaoImpl.java

package jp.abc;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;

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

	public List<MyData> getAll() {
		EntityManager manager = factory.createEntityManager();
		Query query = manager.createQuery("from MyData");
		List<MyData> list = query.getResultList();
		manager.close();
		return list;
	}

	public void add(MyData mydata) {
		EntityManager manager = factory.createEntityManager();
		EntityTransaction tx = manager.getTransaction();
		tx.begin();
		manager.persist(mydata);
		tx.commit();
		manager.close();
	}

	public MyData findById(long id) {
		EntityManager manager = factory.createEntityManager();
		return (MyData)manager.createQuery("from MyData where id = " + id).getSingleResult();
	}

	public MyData findByName(String name) {
		EntityManager manager = factory.createEntityManager();
		return (MyData)manager.createQuery("from MyData where name = " + name).getSingleResult();
	}

	public void update(MyData data) {
		EntityManager manager = factory.createEntityManager();
		EntityTransaction tx = manager.getTransaction();
		tx.begin();
		manager.merge(data);
		tx.commit();
		manager.close();
	}

	public void delete(long id) {
		EntityManager manager = factory.createEntityManager();
		EntityTransaction tx = manager.getTransaction();
		tx.begin();
		manager.remove(id);
		tx.commit();
		manager.close();
	}

}

MyDataDaoImpl の実装が終わったら、次にコントローラに更新のためのメソッドを追加する。

MyDataController.java

package jp.abc;

import java.util.List;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
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.bind.annotation.RequestParam;

@Controller
public class MyDataController {

	@RequestMapping(value = "/mydata", method = RequestMethod.GET)
	public String mydata(Model model) {
		model.addAttribute("title", "MyData");
		model.addAttribute("message", "データを入力してください");
		MyData mydata = new MyData();
		model.addAttribute("myData", mydata);
		MyDataDao<MyData> dao = new MyDataDaoImpl();
		List<MyData> list = dao.getAll();
		model.addAttribute("datalist", list);
		return "mydata";
	}

	@RequestMapping(value = "/mydata", method = RequestMethod.POST)
	public String form(@Valid @ModelAttribute MyData mydata, Errors errors, Model model) {
		if (errors.hasErrors()) {
			model.addAttribute("title", "MyData - エラー");
			model.addAttribute("message", "値をチェックしてください");
			return "mydata";
		}
		MyDataDao<MyData> dao = new MyDataDaoImpl();
		dao.add(mydata);
		return "redirect:/mydata";
	}

	@RequestMapping(value = "/update", method = RequestMethod.GET)
	public String edit(@RequestParam(value = "id")int id, Model model) {
		model.addAttribute("title", "MyData更新");
		model.addAttribute("message", "新しいデータを入力してください");
		MyDataDao<MyData> dao = new MyDataDaoImpl();
		MyData mydata = dao.findById(id);
		model.addAttribute("myData", mydata);
		model.addAttribute("datalist", dao.getAll());
		return "mydata";
	}

	@RequestMapping(value = "/update", method = RequestMethod.POST)
	public String update(@RequestParam(value = "id")int id,
			@Valid @ModelAttribute MyData mydata, Errors result, Model model) {
		MyDataDao<MyData> dao = new MyDataDaoImpl();
		dao.update(mydata);
		return "redirect:/mydata";
	}
}

URLでリクエストパラメータに id を指定すれば、現在の値が表示される。

http://localhost:8080/MyData/update?id=4

update-1

エンティティの削除の実装

MyDataController.java

	@RequestMapping(value = "/delete", method = RequestMethod.GET)
	public String delete(@RequestParam(value = "id")int id, Model model) {
		MyDataDao<MyData> dao = new MyDataDaoImpl();
		dao.delete(id);
		return "redirect:/mydata";
	}

URLでリクエストパラメータに id を指定すれば、対応するエンティティが削除される。

http://localhost:8080/MyData/delete?id=2

9月4日

コントローラの実装

作成したDAOを経由してMyDataを利用するコントローラを作成する。

新規でコントローラクラスを作成する。
クラス名: MyDataController

MyDataController.java

package jp.abc;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class MyDataController {

	@RequestMapping(value = "/mydata", method = RequestMethod.GET)
	public String mydata(Model model) {
		return "mydata";
	}
}

新規にJSPファイルを作成する。
src/main/webapp/WEB-INF/view/mydata.jsp

最初は動作確認のために、シンプルなJSPを作成する。

mydata.jsp

<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>MyData</title>
</head>
<body>
	<h1>${title}</h1>
	<p>${message}</p>
</body>
</html>

次に、サーバーから受け取ったデータを表示できるようにJSPを変更する。

mydata.jsp

<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>MyData</title>
</head>
<body>
	<h1>${title}</h1>
	<p>${message}</p>
	<table>
	<form:form modelAttribute="myData">
		<form:errors path="*" />
		<form:hidden path="id"/>
		<tr>
			<td><form:label path="name">名前</form:label></td>
			<td><form:input path="name" size="20" /></td>
		</tr>
		<tr>
			<td><form:label path="age">年齢</form:label></td>
			<td><form:input path="age" size="20" /></td>
		</tr>
		<tr>
			<td><form:label path="mail">メール</form:label></td>
			<td><form:input path="mail" size="20" /></td>
		</tr>
		<tr>
			<td><form:label path="memo">メモ</form:label>
			<td><form:textarea path="memo" cols="20" rows="5" /></td>
		</tr>
		<tr><td></td><td><input type="submit"></td></tr>
	</form:form>
	</table>
	<hr />
	<c:if test="${datalist != null}">
		<table border="1">
			<tr><th>ID</th><th>名前</th></tr>
			<c:forEach var="obj" items="${datalist}" varStatus="status">
				<tr>
					<td>${obj.id}</td>
					<td>${obj.name}</td>
				</tr>
			</c:forEach>
		</table>
	</c:if>
</body>
</html>

この状態で http://localhost:8080/MyData/mydata/ にアクセスするとJSPが必要としているデータが設定されていないためにエラーになる。
JSP側でアクセスしようとしているデータを、MyDataController で設定する。

MyDataController.java

package jp.abc;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class MyDataController {

	@RequestMapping(value = "/mydata", method = RequestMethod.GET)
	public String mydata(Model model) {
		model.addAttribute("title", "MyData");
		model.addAttribute("message", "データを入力してください");
		MyData mydata = new MyData();
		model.addAttribute("myData", mydata);
		return "mydata";
	}
}

MyDataControllerで必要なデータを設定すれば、画面を表示できるようになる。

バリデーションを有効にするために、pom.xml に dependency を追加する。

pom.xml

		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
			<version>1.1.0.Final</version>
		</dependency>

		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>5.0.1.Final</version>
		</dependency>

今の設定ではTomcatを再起動するとデータベースのテーブルが初期化されるので、設定を変更してデータベースサーバーに保存できるようにする。

Eclipseマーケットプレイスで「HSQLDB」を検索し、「HSQLDB Database Server」をインストールする。
インストール後にEclipseが再起動したら、[ウィンドウ]-[ビューの表示]-[その他]を選択。
「HSQLDB Server」を選択して「OK」すると、下のタブに「HSQLDB Server」が追加される。

以下、設定の変更。

persistence.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  version="2.0"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
      <property name="hibernate.hbm2ddl.auto" value="update" />
      <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbc.JDBCDriver" />
      <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:hsql://localhost/mydatabase" />
    </properties>
  </persistence-unit>
</persistence>

database.properties

database.driverClassName=org.hsqldb.jdbc.JDBCDriver
database.url=jdbc:hsqldb:hsql://localhost/mydatabase
database.username=sa
database.password=

データベースサーバーに接続できるようになったので、コントローラにコードを追加する。

MyDataController.java

package jp.abc;

import java.util.List;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class MyDataController {

	@RequestMapping(value = "/mydata", method = RequestMethod.GET)
	public String mydata(Model model) {
		model.addAttribute("title", "MyData");
		model.addAttribute("message", "データを入力してください");
		MyData mydata = new MyData();
		model.addAttribute("myData", mydata);
		MyDataDao<MyData> dao = new MyDataDaoImpl();
		List<MyData> list = dao.getAll();
		model.addAttribute("datalist", list);
		return "mydata";
	}

	@RequestMapping(value = "/mydata", method = RequestMethod.POST)
	public String form(@Valid @ModelAttribute MyData mydata, Errors errors, Model model) {
		if (errors.hasErrors()) {
			model.addAttribute("title", "MyData - エラー");
			model.addAttribute("message", "値をチェックしてください");
			return "mydata";
		}
		MyDataDao<MyData> dao = new MyDataDaoImpl();
		dao.add(mydata);
		return "redirect:/mydata";
	}
}