Spring 5でできることは?4からの変更点や互換性について解説
この記事は「Javaで学習するSpringによるWebアプリ開発」というトレノキャンプのeラーニング講座を基に解説した記事です。
前回の記事では、Springとデータベースの連携について解説をしました。
今回は、JDBCをラップしたSpring JDBCというクラスを用いてSQLを発行し、実際にデータベースからデータを取得してみましょう。
1.データベースへのアクセス
それでは、実装を通してデータベースの操作を学習していきます。
② 自動で読み込まれるファイルの確認
・ymlファイルの確認
src/main/resources内のapplication.ymlを開いてください。
このapplication.ymlというファイルは自動的に読み込まれるものです。
中身を確認してみましょう。
spring:
datasource:
url: jdbc:h2:mem:test
driverClassName: org.h2.Driver
username: sa
password:
h2.console.enabled: true
spring > datasource はデータベースの設定です。
こちらでは、アクセス用のurlや使用するドライバ、さらに、デフォルトの管理者ユーザーネームなどが記述されています。デフォルトのパスワードは、空白にすることで無しとなっています。
なお、urlの「mem」とはメモリという単語を表しており、起動するたびにデータが初期化されます。
また、H2データベースにはコンソールという仕組みが用意されており、最終行でh2.console.enabledにtrueを指定することで機能を有効化しています。こちらを有効化しておくと、ブラウザからデータベースの様子を確認できるようになります。
・sqlファイルの確認
それでは、次はSpringの起動時に実行されるsqlファイルを確認していきます。
同じくsrc/main/resources内のschema.sqlを開いてください。
schema.sqlはテーブルの構造を記述するsqlファイルです。
CREATE TABLE inquiry
(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
contents VARCHAR(500) NOT NULL,
created DATETIME NOT NULL,
PRIMARY KEY(id)
);
CREATE TABLE survey
(
id INT NOT NULL AUTO_INCREMENT,
age INT NOT NULL,
satisfaction INT NOT NULL,
comment VARCHAR(100),
created DATETIME NOT NULL,
PRIMARY KEY(id)
);
中身はinquiryとsurveyという2つのテーブルが定義されていますが、今回用いるのはこのうちのinquiryという問い合わせデータを入れておくためのテーブルになります。
格納されるデータは、主キーのid、名前、メールアドレス、問い合わせ内容のcontents、そして作成日時のcreatedという構成になっています。
それでは、続いてデータの中身の方を見ていきます。
隣のdata.sqlを開いてください。
中にはINSERT文がいくつか記述されています。
INSERT INTO inquiry(name, email, contents, created)
VALUES('Ethan', 'sample@example.com', 'Hello', '2019-11-12 08:34:19');
INSERT INTO inquiry(name, email, contents, created)
VALUES('Emma', 'sample2@example.com', 'GoodMorning', '2019-12-18 12:10:52');
INSERT INTO inquiry(name, email, contents, created)
VALUES('William', 'sample3@example.com', 'GoodEvening', '2019-12-18 15:10:52');
INSERT INTO survey(age, satisfaction, comment, created)
VALUES(23, 5, 'Good!', '2019-01-03 11:02:35');
INSERT INTO survey(age, satisfaction, comment, created)
VALUES(47, 4, 'Excellent', '2019-02-18 22:35:54');
INSERT INTO survey(age, satisfaction, comment, created)
VALUES(47, 4, 'Excellent', '2019-02-18 22:35:54');
今回、inquiryに対するinsert文は3件登録されており、それぞれnameがEthan、Emma、Williamとなっています。
なお、idはAuto Increment型で自動的に連番がつくため記述されていません。
それでは重要ポイントをおさらいしておきます。
2つのsqlファイル、schema.sqlとdata.sqlがSpring起動時に自動的に実行され、メモリ上のH2データベースへデータが登録されるという流れになっています。
②データが読み込まれていることを確認
ここまで確認できたら、プロジェクトを右クリックし一度Springを実行してください。
Springを起動しただけでデータは読み込まれているはずですので、H2データベースのコンソールにアクセスして確認してみましょう。
ブラウザを開いてアドレスバーに「http://localhost:8080/h2-console」と入力し、アクセスしてください。
コンソール画面が現れました。
初回のアクセス時は「JDBC URL」の欄がmemになっていない場合があるので、「jdbc:h2:mem:test」と書き換え、その他の設定は初期状態のままでConnectをクリックします。
接続が完了し、テーブルの一覧が左側に表示されています。
テーブル一覧からINQUIRYを選択してください。
右側のテキストボックスにSQLが表示されています。
そのままRunを押し、SELECT文を実行してみましょう。
INQUIRYテーブルの内容が表示され、先ほどdata.sqlで登録されていたINSERT文が実行されてデータが実際に登録されていることが確認できました。
2.Javaからデータベース操作
このように、メモリ上でデータベースを動作させることができたので、今度はJavaからこのデータベースを操作してみましょう。
① Controllerクラスの編集
それではEclipseに戻り、SampleController.javaを開いてください。
今回はひとまずお試しとして、/sample/testというURLにアクセスした際に1件自動でデータベースからデータを表示させるというふうにします。
まずは、画像の部分のコメントを解除します。
画像のようにコメントを解除したい部分を選択した状態で、「Ctrl + 7」を押すことでコメントアウトを解除できます。
ここで重要ポイントです。こちらでprivate finalとしてJdbcTemplateというクラスを宣言しています。こちらがJDBCでデータベースを操作するためのクラスとなります。
続いて、同じようにコンストラクタ(画像の18~20行目)のコメントアウトも解除してください。
コンストラクタ内でjdbcTemplateを初期化していますが、ここではnewではなくDI(Dependency Injection)を用いますので、「@Autowired」というアノテーションを付けてください。
//Add an annotation here
public SampleController(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
//Add an annotation here
@Autowired
public SampleController(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
Springにはクラスのnewまで管理する「コンテナ」と呼ばれる仕組みがあり、このように記述することでコンストラクタの引数としてSpringによって自動生成されたJdbcTemplateのインスタンスが渡されます。
そして、コンストラクタの内部でクラスのフィールドへ代入するという流れになっています。
ここまで記述ができたら「Shift + Ctrl + O(オー)」でインポートをしておきましょう。
ということで、これでJDBCが使えるようになりましたのでメソッドの中にデータベース操作の命令を入れていきます。
@GetMapping("/test") // "/sample"以降のURL(GET)
public String test(Model model) {
model.addAttribute("title", "Inquiry Form");
return "test"; //HTMLファイル名
}
@GetMapping("/test") // "/sample"以降のURL(GET)
public String test(Model model) {
String sql = "SELECT id, name, email "
+ "FROM inquiry WHERE id = 1";
Map<String, Object> map = jdbcTemplate.queryForMap(sql);
model.addAttribute("name", map.get("name"));
model.addAttribute("email", map.get("email"));
model.addAttribute("title", "Inquiry Form");
return "test"; //HTMLファイル名
}
まずは、String sqlとして実行するSQL文を定義しています。今回は、inquiryテーブルからid=1のid、name、そしてemailを取得します。こちら長くなってしまうので一度ダブルクォートを閉じ、「+」演算子で文字列の結合を行っています。
その後、早速jdbcTemplateを用いてデータを取得します。
戻り値はMap型、ジェネリクスはString、Objectですので、そのように変数mapを宣言し、jdbcTemplate.queryForMap(sql)でデータを取得しそのまま戻り値で初期化してしまいます。
これで変数mapへ取得したデータを代入できたので、次はこの結果をHTML上で表示するためにModelのaddAttribute()を使ってデータを登録していきます。
こちらもMapと同様にStringとObjectが引数になっているものを選択し、第1引数にカラム名、第2引数にゲッターを用いて取得したデータを指定していきます。
今回はname、emailというカラムを取得したので、それぞれaddAttribute()でModelへ登録しておきます。
それでは、重要ポイントのおさらいです。
はじめにsqlを作成し、JdbcTemplateのqueryForMap()メソッドへ渡し、Map型でデータを取り出します。
そして、さらに取り出したデータをModelのaddAttribute()メソッドを用いて今度はHTMLへ渡しています。
package com.example.demo.app;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
/*
* Add annotations here
*/
@Controller //Controllerクラスに付与
@RequestMapping("/sample") //ドメイン以降のURL
public class SampleController {
private final JdbcTemplate jdbcTemplate;
//Add an annotation here
@Autowired
public SampleController(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@GetMapping("/test") // "/sample"以降のURL(GET)
public String test(Model model) {
String sql = "SELECT id, name, emaail "
+ "FROM inquiry WHERE id = 1";
Map<String, Object> map = jdbcTemplate.queryForMap(sql);
model.addAttribute("name", map.get("name"));
model.addAttribute("email", map.get("email"));
model.addAttribute("title", "Inquiry Form");
return "test"; //HTMLファイル名
}
}
最終的なコードは以上のようになります。
②HTMLファイルの編集
今度はHTMLファイルの方を編集していきます。
一旦保存をして、test.htmlのファイルを開いてください。
こちらでは<p>タグを使ってModelに設定した値を取り出すということをやっていきます。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title th:text="${title}">Insert title here</title>
</head>
<body>
<h1 th:text="${title}">title</h1>
<p th:text="${name}">name</p>
<p th:text="${email}">email</p>
<!-- These are links to use for next lessons -->
<!-- こちらは後で使用されるリンクです -->
<p><a href="#" th:href="@{/inquiry}">Inquiry</a></p>
<p><a href="#" th:href="@{/survey}">Survey</a></p>
</body>
</html>
<p>タグで値を取り出すためにはth:text=${キー}という記述を用いました。
今回nameとemailという2つのデータがありますので、<p>タグも2つ用意し、それぞれth:textに指定するキーおよび<p>タグの中身をname、emailとしておきます。
ここまで書けたら保存をかけます。
これでHTMLファイルが完成しました。
3.ブラウザからアクセス
それでは、ここから検証ポイントです。ブラウザから実際にアクセスしてみて、表示を確認しましょう。
「http://localhost:8080/sample/test」へアクセスします。
このように、データベースから取得した名前Ethan、メールアドレスsample@example.comが表示されました。
以上で今回の実践は完了です。お疲れさまでした。
第2章 Springの基本
以降アプリ制作を行うにあたって、Springを使う環境を作っていきましょう。
Gradleプロジェクトのインポート方法、プロジェクトを確認する方法を紹介します。
制作に慣れるため、SpringのMVCアーキテクチャの体験、データのブラウザへの出力を行いましょう。
それにともなって、ビルドツールの「Gradle」や記述方法の「アノテーション」、テンプレートエンジンの「Thymeleaf」についても解説していきます。
手順に沿ってデータをブラウザに出力していきましょう。
アノテーションの付与、リクエストスコープが実際どのように使われているのか、Thymeleafを使う際の注意点などを確認していきます。
Springからデータベースを操作する方法について確認します。
ここでは一番シンプルな、Controllerから直接データベースへアクセスしてデータを取得する処理を見ていきましょう。
実際にデータベースを操作します。
データベースのアクセスに用いるSpringJDBCクラスの使われ方を確認しましょう。
第3章 お問い合わせアプリ開発
まずはこれから作成していくフォームの構成を確認してから、
フォームの作成に必要なHTMLファイル、Formクラスの作成方法を見ていきましょう。
HTMLファイル、Formクラスの編集を行いながらフォームを完成させましょう。
フォームで入力したデータを次のページに渡す方法を学び、確認ページを作ります。
hiddenタグを用いた作成方法、バリデーションの行い方を学びましょう。
実際に確認ページの作成を行っていきましょう。
HTMLの編集、バリデーションを含めた確認処理の実装を行います。
リダイレクト、フラッシュスコープなどの完了処理を作っていきます。
それぞれの作成方法、リダイレクトの仕組みについても確認しておきましょう。
実際にControllerに追加記述をして、リダイレクト、フラッシュスコープの実装を行います。
HTMLとの対応も確認しましょう。