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

3.1.4.(JdbcTemplate)(複数テーブルの結合) Spring+MVC+DB+Test構築サンプル

前提

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

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


目次

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

1.Entityクラスの作成

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

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

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

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

public class StaffAndDepartment {
	private Long id;
	private String name;
	private Integer age;
	private Long deptid;
	private String deptname;
	
	public StaffAndDepartment() {
	}
	
	public StaffAndDepartment(
			Long id,
			String name,
			Integer age,
			Long deptid,
			String deptname) {
		this();
		this.id = id;
		this.name = name;
		this.age = age;
		this.deptid = deptid;
		this.deptname = deptname;
	}

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

	public String getDeptname() {
		return deptname;
	}

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


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

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

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

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

import java.util.List;

import jp.mitchy.entity.StaffAndDepartment;

public interface StaffAndDepartmentDao {
	public List<StaffAndDepartment> getAllEntity();
}
今回は2テーブル全レコード取得のメソッドのみです


3.Daoクラスの作成

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

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

作成された「StaffAndDepartmentDaoImpl.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.StaffAndDepartmentDao;
import jp.mitchy.entity.StaffAndDepartment;

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

	public List<StaffAndDepartment> getAllEntity() {
		System.out.println("getAllEntity()");
		return jdbcTemplate.query(
				"SELECT S.id, S.name, S.age, S.deptid, D.name as deptname FROM Staff S JOIN Department D ON S.deptid = D.id",
				new BeanPropertyRowMapper<StaffAndDepartment>(StaffAndDepartment.class));
	}
}
特に改めて解説すべきところはないので説明は割愛します。


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

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

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

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

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

public interface StaffAndDepartmentService {
	public TestResultDto<StaffAndDepartment> execute();
}
TestResultDto を返す execute メソッドのみのシンプルなインタフェースです


5.Serviceクラスの作成

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

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

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

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import jp.mitchy.dao.StaffAndDepartmentDao;
import jp.mitchy.dto.TestResultDto;
import jp.mitchy.entity.StaffAndDepartment;
import jp.mitchy.service.StaffAndDepartmentService;

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

	public TestResultDto<StaffAndDepartment> execute(){
		TestResultDto<StaffAndDepartment> result = new TestResultDto<StaffAndDepartment>();
		
		result.setEntity(null);
		
		// SELECT 複数
		List<StaffAndDepartment> list = dao.getAllEntity();
		result.setList(list);

		return result;
	}
}
基本的に前の章で作成した内容から特に新しいものは出てきていないので
説明は割愛します。


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.Attendance;
import jp.mitchy.entity.Department;
import jp.mitchy.entity.Staff;
import jp.mitchy.entity.StaffAndDepartment;
import jp.mitchy.service.AttendanceService;
import jp.mitchy.service.DepartmentService;
import jp.mitchy.service.StaffAndDepartmentService;
import jp.mitchy.service.StaffService;

@RequestMapping("/test/*")
@Controller
public class TestController {
	
	@Autowired
	private DepartmentService deptService;
	
	@Autowired
	private StaffService staffService;
	
	@Autowired
	private AttendanceService attendService;
	
	@Autowired
	private StaffAndDepartmentService staffDeptService;
	
	@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";
	}
	
	@RequestMapping(value = "/attend", method = RequestMethod.GET)
	public String attend(Model model) {
		// ------------------------------
		// 複合主キーを持つテーブルのCURD確認
		// ------------------------------
		
		Attendance entity = new Attendance(201L, 20180101, 1);
		
		// サービスの実行
		TestResultDto<Attendance> dto = attendService.execute(entity);

		// 結果をセット
		model.addAttribute("data", dto.getEntity());
		model.addAttribute("list", dto.getList());
		
		// view/test/result.jsp を表示
		return "test/result";
	}
	
	@RequestMapping(value = "/staffdept", method = RequestMethod.GET)
	public String staffdept(Model model) {
		// ------------------------------
		// 複数テーブルの結合
		// ------------------------------
		
		// SELECT 複数
		TestResultDto<StaffAndDepartment> dto = staffDeptService.execute();

		// 結果をセット
		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/>
		<c:url value="/test/attend" var="messageUrl3" />
		<a href="${messageUrl3}">Attendance Test</a><br/>
		<c:url value="/test/staffdept" var="messageUrl4" />
		<a href="${messageUrl4}">Staff and Department Test</a><br/>
	</body>
</html>


8.確認実行

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

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

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

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

以上で JdbcTemplate を使った複数テーブルの結合の
サンプル構築は完了です。


ダウンロード

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


更新履歴

2018/10/08 新規作成

TOPJavaspring → This Page
Valid CSS!