前回の第九回ではデータベースに接続し絞込みを行いログイン処理を実装しました。
今回は、テーブルの結合をしてデータを取得していきます。
Spring Framework連載記事 目次
【第一回】Spring Frameworkを使ってみる ~Spring Framework概要と準備~
【第二回】Spring Frameworkを使ってみる ~プロジェクト作成からビルドまで~
【第三回】Spring Frameworkを使ってみる ~サーバで実行~
【第四回】Spring Frameworkを使ってみる ~画面遷移~
【第五回】Spring Frameworkを使ってみる ~データ受け渡し~
【第六回】Spring Frameworkを使ってみる ~入力値チェック~
【第七回】Spring Frameworkを使ってみる ~データベースにアクセスする①~
【第八回】Spring Frameworkを使ってみる ~データベースにアクセスする②~
【第九回】Spring Frameworkを使ってみる ~データベースにアクセスする③~
【第十回】Spring Frameworkを使ってみる ~データベースにアクセスする④~
準備
テーブルの再作成
まずは、前回まで使用していたテーブルをいったん削除して下記のテーブル作成スクリプトを実行します。
1 2 3 4 5 6 7 8 9 10 11 | CREATE TABLE department (id INTEGER PRIMARY KEY,name VARCHAR(40));CREATE TABLE user (id INTEGER PRIMARY KEY,name VARCHAR(40),department_id INTEGER,FOREIGN KEY (department_id)REFERENCES department (id)); |
テーブルにデータ挿入
下記のスクリプトを実行し、テーブルにデータを挿入します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | INSERT INTO department (id,name)VALUES (1,'人事部');INSERT INTO department (id,name)VALUES (2,'営業部');INSERT INTO user (id,name,department_id)VALUES (1,'田中',1);INSERT INTO user (id,name,department_id)VALUES (2,'佐藤',1);INSERT INTO user (id,name,department_id)VALUES (3,'鈴木',2); |
モデルの削除
JPAを使用してモデル作成
モデルの作成
前々回と同様にJPAを使用してモデルを作成していきます。
「model」パッケージを右クリック⇒「New」⇒「other…」を選択します。

「JPA」⇒「JPA Entities from Tables」を選択します。

Connectionを選択して、先ほど作成した「department」テーブルと「user」テーブルにチェックを入れます。
チェック後、「Finish」を選択します。

モデルの内容確認
作成方法は前々回と同様ですが、今回は、テーブルにプライマリキーと外部キーがしっかりと張られています。
そのことによりJPAからテーブルを作成したときに、すでに結合した結果が取得できるようになっています。
具体的には作成されたモデルの下記の部分を見てみましょう。
User.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | package jp.ssie.helloworld.model;import java.io.Serializable;import javax.persistence.*;/*** The persistent class for the user database table.**/@Entity@NamedQuery(name="User.findAll", query="SELECT u FROM User u")public class User implements Serializable {private static final long serialVersionUID = 1L;@Idprivate int id;private String name;//bi-directional many-to-one association to Department@ManyToOneprivate Department department;public User() {}public int getId() {return this.id;}public void setId(int id) {this.id = id;}public String getName() {return this.name;}public void setName(String name) {this.name = name;}public Department getDepartment() {return this.department;}public void setDepartment(Department department) {this.department = department;}} |
20行目、21行目に「@ManyToOne」アノテーションと「Department」クラスの変数が出来上がっています。
この記述があると「User」テーブルのデータを取得した際に、それに紐づく「Department」テーブルのデータを取得することができます。
つまり、テーブルの外部キーなどがしっかりと貼られていれば、SQLを記述することなくテーブルの結合した結果を取得することができます。
アノテーションの「@ManyToOne」は多対1という意味になります。
ここでは「ユーザ:多」に対し「部署:1」になります。
「Department.java」についても確認してみます。
Department.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | package jp.ssie.helloworld.model;import java.io.Serializable;import javax.persistence.*;import java.util.List;/*** The persistent class for the department database table.**/@Entity@NamedQuery(name="Department.findAll", query="SELECT d FROM Department d")public class Department implements Serializable {private static final long serialVersionUID = 1L;@Idprivate int id;private String name;//bi-directional many-to-one association to User@OneToMany(mappedBy="department")private List<User> users;public Department() {}public int getId() {return this.id;}public void setId(int id) {this.id = id;}public String getName() {return this.name;}public void setName(String name) {this.name = name;}public List<User> getUsers() {return this.users;}public void setUsers(List<User> users) {this.users = users;}public User addUser(User user) {getUsers().add(user);user.setDepartment(this);return user;}public User removeUser(User user) {getUsers().remove(user);user.setDepartment(null);return user;}} |
21行目、22行目で「User」テーブルと同様に、「@OneToMany」アノテーションと「User」クラスのリスト変数が出来上がっています。
Userと違い、「部署:1」に対し「ユーザ:多」になるので、それをあらわすアノテーションが付与されています。
また、「部署:1」に対し「ユーザ:多」なので、取得する「User」クラスはリストになっています。
出力内容の変更
ログイン後に前回出力した名前だけでなく、部署名を出力していきます。
LoginControllerの編集
ログイン時に取得する値に部署名を追加します。
JPAが結合を自動で行ってくれるので、取得した結果から「getDepartment」するだけで部署テーブルの内容を取得することができます。
LoginController.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | package jp.ssie.helloworld.web;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.validation.BindingResult;import org.springframework.validation.annotation.Validated;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import jp.ssie.helloworld.form.LoginForm;import jp.ssie.helloworld.model.User;import jp.ssie.helloworld.repository.UserRepository;import jp.ssie.helloworld.validation.GroupOrder;@Controllerpublic class LoginController {@Autowiredprivate UserRepository userRep;@RequestMapping(value = "/", method = RequestMethod.GET)public String index(Model model) {return "index";}@RequestMapping(value = "/login", method = RequestMethod.POST)public String login(Model model, @Validated(GroupOrder.class) @ModelAttribute("loginForm") LoginForm loginForm, BindingResult result) {if(result.hasErrors()) {return "index";}List<User> userList = userRep.findById(loginForm.getUserId());if(userList.size() > 0) {model.addAttribute("userName", userList.get(0).getName());model.addAttribute("departmentName", userList.get(0).getDepartment().getName());return "top";} else {return "index";}}} |
39行目でとくに難しいことはせずに、EntityのGetterメソッドのみで部署名を取得していきます。
top.jspの編集
設定した部署名を画面に出力します。
top.jspを下記のように変更します。
top.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <!DOCTYPE html><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><html><head><meta charset="utf-8"><title>トップ</title></head><body>ようこそ<c:out value="${departmentName}" />の<c:out value="${userName}" />さん</body></html> |
実行結果
実行
非常に簡単にテーブルの結合を実現することができました。
次回について
今回はデータベースのテーブルを結合して値を取得しました。簡単なものであればこれで十分と思われるので、次回からは画面の出力について調査していきます。







PAGE TOP