タイトル
 メニューにないコーナーはTopからいけます
TOPJavaspring → This Page

3.1.2.(JdbcTemplate)(N:1テーブルのCRUD) Spring+MVC+DB+Test構築サンプル

前提

このページに記載している内容は 2018/09/30 に書かれたものです。
掲載している画面や方法が将来的に変更されている場合があります。
また、掲載しているインストール方法は Windows 8.1 の場合です。
開発環境は
・Windows 8.1
・JDK 8
・STS(Spring Tool Suite) 3.9.5
・PostgreSQL 9.5.14
とします。

本ページは先に以下の3ページの内容を実施してからの内容となります。
1.準備
2.共通部分構築
3.1.1.JdbcTemplate 単一テーブルのCRUD

JdbcTemplate は SQL を発行して結果を返すだけのシンプルな機能しかないため、
実は本ページの「N:1テーブルのCRUD」は前章の「単一テーブルのCRUD」となんら変わりません。
他のDBアクセス方法のページに章構成を合わせるために作っただけです。
そのため、適当に読み飛ばして次に進んでも大丈夫です。


目次

1.Entityクラスの作成
2.Daoインタフェースの作成
3.Daoクラスの作成
4.Serviceインタフェースの作成
5.Serviceクラスの作成
6.TestController.java編集
7.index.jsp編集
8.確認実行

1.Entityクラスの作成

今回は「N:1テーブルのCRUD」ということで、
準備編で用意したテーブル「staff」テーブルを使うことにします。
「staff」テーブルは「department」テーブルと外部結合でつながっています。
「staff」テーブルからみると「department」テーブルとの関係は「N:1」です。
(複数のスタッフが同じ1つの部門に属している状態)
図:department

1テーブルにつき対応した1Entityクラスを作成します。
プロジェクト名を右クリックして「New」>「Class」を選択します。
図:STS

「New Java Class」ダイアログが表示されます。
・「Package」は「jp.mitchy.entity」と入力
・「Name」は「Staff」と入力
・それ以外の項目はそのまま
「Finish」ボタンを押します。
図:New Java Class

作成された「Staff.java」が開くので、内容を以下のように書き換えて保存しましょう。
package jp.mitchy.entity;

public class Staff {
	private Long id;
	private String name;
	private Integer age;
	private Long deptid;
	
	public Staff() {
	}

	public Staff(Long id, String name, Integer age, Long deptid) {
		this();
		this.id = id;
		this.name = name;
		this.age = age;
		this.deptid = deptid;
	}

	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 Integer getAge() {
		return age;
	}

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

	public Long getDeptid() {
		return deptid;
	}

	public void setDeptid(Long deptid) {
		this.deptid = deptid;
	}
	
	@Override
	public String toString() {
		return "[id=" + id + ",name=" + name + ",age=" + age + ",deptid=" + deptid + "]";
	}
	
}
テーブルのカラムに合わせて id, name, age, deptid をメンバフィールドに持ちます。
あとはコンストラクタと表示用の toString メソッドだけの簡単な構造です。


2.Daoインタフェースの作成

同じく1テーブルにつき対応した1DAOインタフェースを作成します。
プロジェクト名を右クリックして「New」>「Interface」を選択します。
図:STS

「New Java Interface」ダイアログが表示されます。
・「Package」は「jp.mitchy.dao」と入力
・「Name」は「StaffDao」と入力
・それ以外の項目はそのまま
「Finish」ボタンを押します。
図:New Java Interface

作成された「StaffDao.java」が開くので、内容を以下のように書き換えて保存しましょう。
package jp.mitchy.dao;

import java.util.List;

import jp.mitchy.entity.Staff;

public interface StaffDao {
	public List<Staff> getAllEntity();
	public Staff findById(Long id);
	public void addEntity(Staff entity);
	public void updateEntity(Staff entity);
	public void removeEntity(Staff data);
	public void removeEntity(Long id);
}
メソッド名を見てなんとなく何をするメソッドか想像はつくと思いますが、
上からそれぞれ
・全レコード取得
・1レコード取得
・レコード追加
・レコード更新
・レコード削除(引数がエンティティ)
・レコード削除(引数がID)
です


3.Daoクラスの作成

先ほど作成したインタフェースを実装したクラスを作成します。
同じく1テーブルにつき対応した1DAOクラスを作成します。
プロジェクト名を右クリックして「New」>「Class」を選択します。
図:STS

「New Java Class」ダイアログが表示されます。
・「Package」は「jp.mitchy.dao.impl」と入力
・「Name」は「StaffDaoImpl」と入力
・それ以外の項目はそのまま
「Finish」ボタンを押します。
図:New Java Class

作成された「StaffDaoImpl.java」が開くので、内容を以下のように書き換えて保存しましょう。
package jp.mitchy.dao.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
// import org.springframework.web.context.support.SpringBeanAutowiringSupport;

import jp.mitchy.dao.StaffDao;
import jp.mitchy.entity.Staff;

@Repository
public class StaffDaoImpl implements StaffDao {
	
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	public StaffDaoImpl() {
		init();
	}
	
	public void init(){
		// @Autowired がうまく機能しない場合は以下のコメントを外す
		// SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
	}

	public List<Staff> getAllEntity() {
		System.out.println("getAllEntity()");
		/**
		// 結果がMapでいいならqueryForList(sql)が一番シンプルに取得できる
		List<Map<String, Object>> list = jdbcTemplate.queryForList("SELECT * FROM Staff");
		// ただしEntityには自力で変換が必要
		List<Staff> result = new ArrayList<Staff>();
		for ( Map<String, Object> map : list ) {
			Staff entity = new Staff( (Long)map.get("id"), (String)map.get("name"), (Long)map.get("deptid"));
			result.add(entity);
		}
		return result;
		*/
		return jdbcTemplate.query("SELECT * FROM Staff",
				new BeanPropertyRowMapper<Staff>(Staff.class));
	}

	public Staff findById(Long id) {
		return jdbcTemplate.queryForObject("SELECT * FROM Staff WHERE id = ?",
				new Object[] { id },
				new BeanPropertyRowMapper<Staff>(Staff.class));
	}
	
	public void addEntity(Staff entity) {
		System.out.println("addEntity(entity)");
		jdbcTemplate.update("INSERT INTO Staff VALUES(?, ?, ?, ?)",
				entity.getId(), entity.getName(), entity.getAge(), entity.getDeptid());
	}

	public void updateEntity(Staff entity) {
		System.out.println("updateEntity(entity)");
		jdbcTemplate.update("UPDATE Staff SET name = ?, age = ?, deptid = ? WHERE id = ?",
				entity.getName(), entity.getAge(), entity.getDeptid(), entity.getId());
	}

	public void removeEntity(Staff entity) {
		System.out.println("removeEntity(entity)");
		jdbcTemplate.update("DELETE FROM Staff WHERE id = ?",
				entity.getId());
	}

	public void removeEntity(Long id) {
		System.out.println("removeEntity(id)");
		jdbcTemplate.update("DELETE FROM Staff WHERE id = ?",
				id);
	}

}
基本的に前の章で作成した「DepartmentDaoImpl」とほぼ同じなので
説明は割愛します。


4.Serviceインタフェースの作成

次にサービス層のインタフェース・クラスを作ります。
今回もまずはインタフェースを作成します。
プロジェクト名を右クリックして「New」>「Interface」を選択します。
図:STS

「New Java Interface」ダイアログが表示されます。
・「Package」は「jp.mitchy.service」と入力
・「Name」は「StaffService」と入力
・それ以外の項目はそのまま
「Finish」ボタンを押します。
図:New Java Interface

作成された「StaffService.java」が開くので、内容を以下のように書き換えて保存しましょう。
package jp.mitchy.service;

import jp.mitchy.dto.TestResultDto;
import jp.mitchy.entity.Staff;

public interface StaffService {
	public TestResultDto<Staff> execute(Staff entity);
}
エンティティを引数とし、TestResultDto を返す execute メソッドのみのシンプルなインタフェースです


5.Serviceクラスの作成

先ほど作成したインタフェースを実装したクラスを作成します。
プロジェクト名を右クリックして「New」>「Class」を選択します。
図:STS

「New Java Class」ダイアログが表示されます。
・「Package」は「jp.mitchy.service.impl」と入力
・「Name」は「StaffServiceImpl」と入力
・それ以外の項目はそのまま
「Finish」ボタンを押します。
図:New Java Class

作成された「StaffServiceImpl.java」が開くので、内容を以下のように書き換えて保存しましょう。
package jp.mitchy.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
//import org.springframework.web.context.support.SpringBeanAutowiringSupport;

import jp.mitchy.dao.StaffDao;
import jp.mitchy.dto.TestResultDto;
import jp.mitchy.entity.Staff;
import jp.mitchy.service.StaffService;

@Service
public class StaffServiceImpl implements StaffService {
	
	@Autowired
	private StaffDao dao;
	
	public StaffServiceImpl() {
		init();
	}
	
	public void init(){
		// @Autowired がうまく機能しない場合は以下のコメントを外す
		// SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
	}

	public TestResultDto<Staff> execute(Staff entity) {
		TestResultDto<Staff> result = new TestResultDto<Staff>();
		
		// INSERT
		dao.addEntity(entity);
		
		// UPDATE
		entity.setName("退職太郎3");
		dao.updateEntity(entity);
		
		// DELETE
		dao.removeEntity(entity.getId());
		
		// SELECT 単体
		Staff entity2 = dao.findById(102L);
		result.setEntity(entity2);
		
		// SELECT 複数
		List<Staff> list = dao.getAllEntity();
		result.setList(list);

		return result;
	}
	
}
こちらも基本的に前の章で作成した「DepartmentServiceImpl」とほぼ同じなので
説明は割愛します。


6.TestController.java編集

jp.mitchy.controller にある TestController.java を変更し、
今回作成したサービスを呼び出して実行するようにします。
内容を以下のように書き換えて保存しましょう。
赤文字が前回から追加になる箇所です。
package jp.mitchy.controller;

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

import jp.mitchy.dto.TestResultDto;
import jp.mitchy.entity.Department;
import jp.mitchy.entity.Staff;
import jp.mitchy.service.DepartmentService;
import jp.mitchy.service.StaffService;

@RequestMapping("/test/*")
@Controller
public class TestController {
	
	@Autowired
	private DepartmentService deptService;
	
	@Autowired
	private StaffService staffService;
	
	@RequestMapping(value = "/dept", method = RequestMethod.GET)
	public String dept(Model model) {
		// ------------------------------
		// 単テーブルのCURD確認
		// ------------------------------
		
		Department entity = new Department(4L, "新事業部");
		
		// サービスの実行
		TestResultDto<Department> dto = deptService.execute(entity);
		
		// 結果をセット
		model.addAttribute("data", dto.getEntity());
		model.addAttribute("list", dto.getList());

		// view/test/result.jsp を表示
		return "test/result";
	}
	
	@RequestMapping(value = "/staff", method = RequestMethod.GET)
	public String staff(Model model) {
		// ------------------------------
		// N:1 テーブルのCURD確認
		// ------------------------------
		
		Staff entity = new Staff(103L, "人事太郎3", 50, 1L);
		
		// サービスの実行
		TestResultDto<Staff> dto = staffService.execute(entity);
		
		// 結果をセット
		model.addAttribute("data", dto.getEntity());
		model.addAttribute("list", dto.getList());

		// view/test/result.jsp を表示
		return "test/result";
	}
	
}

こちらも基本的に前の章で作成したメソッドとほぼ同じなので
説明は割愛します。


7.index.jsp編集

最後に、作成した処理を呼び出せるように index.jsp を編集します。
src/main/webapp/index.jsp を開き、内容を以下のように書き換えて保存しましょう。
赤文字が前回から追加になる箇所です。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>

<html>
	<head>
		<meta charset="utf-8">
		<title>Welcome</title>
	</head> 
	<body>
		<c:url value="/test/dept" var="messageUrl1" />
		<a href="${messageUrl1}">Department Test</a><br/>
		<c:url value="/test/staff" var="messageUrl2" />
		<a href="${messageUrl2}">Staff Test</a><br/>
	</body>
</html>


8.確認実行

念のためにいつもの「Maven Clean」「Maven Install」をやっておきましょう。
エラーが出たら「Project」>「Clean」をやってから
再度「Maven Install」です。

次にプロジェクト名を右クリックして「Run As」>「Run On Server」を選択します。
図:STS

少し時間がかかりますが「Console」に状況が表示されていきます。
しばらくすると内蔵ブラウザが立ち上がり、「Staff Test」が表示されます。
図:ブラウザ

「Staff Test」のリンクをクリックしてみましょう。
リンク先 /test/staff に連動する TestController クラスの staff メソッドが呼び出され、
/WEB-INF/view/test/result.jsp が表示されることが確認できます。
テーブル操作も正常に実行されていますね。
(Consoleの出力内容も確認してみましょう)
図:ブラウザ

以上で JdbcTemplate を使ったN:1テーブルのCRUDの
サンプル構築は完了です。


ダウンロード

作成したプロジェクトのソースをダウンロードできます。
312WebDbSample1JdbcTemplate.zip


更新履歴

2018/09/30 新規作成

TOPJavaspring → This Page
Valid CSS!