はじめに
Spring Boot で MySQL を使用した新規プロジェクトを作成する手順について備忘として書いておきます。
初心者でも、MVCのデータの流れが分かるように、なるべく丁寧に記録を残しておきます。
本記事の内容は、2021年7月現在のもので、使用する環境・設定などは次のとおりです(※2024年7月現在に合わせて一部記事を修正しました)。
項目 | 内容 | インストール方法など |
---|---|---|
IDE | Eclipse または Spring Tool Suite4 *注1 | Eclipse Java動作環境の構築とインストール、STSのインストール方法 |
OS | Windows 10 | |
データベース | MySQL | MySQLインストール方法 |
DB接続のAPI | JDBC API | |
ビルドツール | Gradle | (Mavenの場合も併記) |
JDK | OpenJDK、AdoptOpenJDK *注2 | 特に何もしなければ OpenJDK が適用されます。 AdoptOpenJDK導入方法、STSでAdoptOpenJDK使用 |
※注1(2024/7/27追記) 久しぶりに STS をインストールして使用してみましたが、いろいろとエラーが出やすいため、現時点では、Eclipse を使用した方が良さそうです。Eclipse をインストールすると、デフォルトで STS も入っていました。
※注2(2024/7/27追記) 本記事の作成当時は OpenJDK が有償化されていたため AdoptOpenJDK を使用していました。しかし、現在は、OpenJDK も無償利用できるようになりましたので、何もせず、そのまま OpenJDK を使用すれば OK だと思います。
記事の作成に当たっては、以下のサイトを参考にさせていただきました。
<参考記事>
・SpringBoot + Spring JPAでデータベースに接続する
・Spring Boot + Spring JDBC で MySQL に接続するための設定
・Spring Boot で Spring JDBC を使う
・JPA で MySQL データアクセス
・Spring BootでのDBアクセス方法(JDBC、JPA、MyBatis)について
・【超入門Java】Spring Bootを使って画面表示をしてみる
1. Spring Bootプロジェクトの作成
まず、**Spring Tool Sweet(STS)**のメニューから、「File」→「New」→「Spring Starter Project」の順で選択します。
New Spring Starter Project
最初に「New Spring Starter Project」という画面が表示されます。
ここでは、Name
を適当に設定して(プロジェクト名なので何でも良い)、Type
(ビルドツール)を **Gradle(グレイドル)**にしておきます。
Java Version
は11にしています。なお、Artifact
は、Name と連動して自動的に書き換えられます。
各項目の内容はおおよそ次のとおりです。
項目 | 内容 |
---|---|
Service URL(サービスURL) | Spring Bootプロジェクトの雛形を生成する「SPRING INITIALIZR」のURL |
Name(名前) | プロジェクト名 |
Type(型) | ビルドツールの選択 |
Java Version(Java バージョン) | Javaのバージョンを選択 |
Packaging(パッケージング) | Jar又はWarから選択 |
Language(言語) | プログラミング言語を選択 |
Group(グループ) | プロジェクトを一意に識別する名前 |
Artifact(成果物) | プロジェクトの成果物の名前 |
Version(バージョン) | プロジェクトのバージョン |
Description(説明) | 説明文 |
Package(パッケージ) | パッケージ名 |
New Spring Starter Project Dependencies
次に、「New Spring Starter Project Dependencies」という画面が表示されます。
ここでは、使用するライブラリを選択します。
選択したライブラリを元に「build.gradle」というビルドスクリプトが自動作成されます(後述)。
なお、ライブラリは後からでも追加できます。
今回のサンプル作成では、次の5つのライブラリを指定しておきます。
区分 | ライブラリ | 備考 |
---|---|---|
Developer Tools | Spring Boot DevTools | サーバを再起動しなくてもコードの修正が反映される |
SQL | JDBC API | Javaからデータベースを操作するインターフェイス |
SQL | MySQL Driver | MySQLへの接続ドライバ |
Template Engines | Thymeleaf | ビューを作成するためのテンプレートエンジン |
Web | Spring Web | WEBアプリを構築するためのスターター |
選択したら、Finish を押します。
プロジェクトが作成されるまで、少々時間が掛かりますので、気長に待ちます。
※ 2024/7/27追記 今回の作成プロジェクトでは不要と思いますが、Gradle の場合は、以下の Validation も追加した方が良さそうです(影響範囲は未確認)。
<参考記事>
・Spring Boot をはじめてみるよ
・Spring Bootで基本的なWebプロジェクトの作成
・Spring Boot でWebアプリを開発してみよう Vol.2
・STS(Spring Tool Suite)3.9.0で「Springスタータープロジェクト」が少し進化してました。
2. 作成された新規プロジェクトの確認
プロジェクトが作成されると、STS の Package Explorer に、次のようなディレクトリが作成されています。
数々のファイルが自動生成されていますが、その中でも、押さえておくべきは赤枠で囲んだ3つのファイルです。
3つのファイルのうち、TestAppApplication.java と build.gradle は、コードが自動生成されています。
application.properties の中身は空っぽなので、後でコードを書きます。
以下、順に見ていきます。
mainメソッド(自動生成)
まず、TestAppApplication.java をダブルクリックして開いてみると、コードが次のように自動生成されています。
これは、WEBアプリを起動するための mainメソッドです。
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class TestAppApplication {
public static void main(String[] args) {
SpringApplication.run(TestAppApplication.class, args);
}
}
クラス名は「プロジェクト名 + Application」となっています。
今回は、TestAppApplication
となってしまい、Appが重複してしまいました(失敗しました)。
ちょっと格好悪いですが、特に動作には影響ないのでこのままにしておきます。
ざっくりとコードを見ると、SpringApplicationクラスのrunメソッドでアプリケーションを起動しているという感じですね。
build.gradle(自動生成)
build.gradle
には、次のようなビルドスクリプトが自動生成されています(ダブルクリックで開きます)。
Spring Starter Project で色々と選択した内容が反映されているのが何となく分かると思います。
plugins {
id 'org.springframework.boot' version '2.4.4'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'mysql:mysql-connector-java'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
言うまでもないですが、作成時にチェックしたライブラリと build.gradle ファイルの対応関係は次のようになっています。
選択したライブラリ | dependenciesに反映された内容 |
---|---|
Spring Boot DevTools | spring-boot-devtools |
JDBC API | spring-boot-starter-jdbc |
MySQL Driver | mysql-connector-java |
Thymeleaf | spring-boot-starter-thymeleaf |
Spring Web | spring-boot-starter-web |
(参考1)ビルドスクリプト(build.gradle)の修正方法
ビルドスクリプト(build.gradle)を修正して、ライブラリを追加する方法も書いておきます(もっと簡単なやり方があるのかもしれませんが)。
例えばバリデーションに関するライブラリを追加するならば、dependencies
の波括弧の中に次の1行を追加します。
implementation 'org.springframework.boot:spring-boot-starter-validation'
追加したらファイルを保存します。
そして、次のように、プロジェクトの上で右クリックをして、「Gradle」→「Refresh Dependencies」と操作すれば、ビルドスクリプトが更新されてライブラリが追加されます。
(参考2)Mavenを使用した場合
ビルドツールに Maven(メイヴン) を使用した場合は、次のような pom.xml ファイルが自動生成されます。
一見難しいように見えますが行数が多いだけで、書いてある内容は Gradle とほぼ変わりません(タグは一旦無視して、白い文字を中心に読むと分かりやすいです)。
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>TestApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>TestApp</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3. MySQLでデータベースを作成
ここで、プロジェクトに使用するデータベースを作成しておきます。
データベース管理システムとして MySQL を使用しますので、コマンドプロンプトから MySQL を立ち上げて、WEBアプリ用の「データベース」と「ユーザー」を作成しておきます。
MySQLの操作の詳細についてはここでは書きませんので、「MySQLの使い方」というサイトなどを参照してください。
データベースの作成
CREATE DATABASE文で spring_test というデータベースを作成しておきます。
データベース名は何でも構いません。ここで付けた名前を後で application.properties ファイルに記述することになります。
mysql> create database spring_test;
Query OK, 1 row affected (0.33 sec)
ユーザーの作成
CREATE USER文で、アクセス用のユーザーを作成しておきます。
ここでは、ユーザー名:yama3、パスワード:123456 としておきました。
ユーザー名とパスワードも、後述の application.properties ファイルに記述することになります。
mysql> create user 'yama3'@'localhost' identified by '123456';
Query OK, 0 rows affected (0.32 sec)
次のように、権限の設定も行います。
これで、spring_test
というデータベースに対して全ての権限が与えられます。
mysql> grant all on spring_test.* to 'yama3'@'localhost';
Query OK, 0 rows affected (0.23 sec)
4. アプリケーションプロパティの設定
先ほど少し触れましたが、application.properties というファイルが生成されていますので、ここにデータベースに関する設定を記述します(ファイルはsrc/main/resources
のフォルダに入っています)。
なお、Spring Boot のバージョンによって書き方が異なるため、2.4.4
、2.5.0
、2.5.1
の場合についてそれぞれ書いておきます。
それ以外のバージョンでも、アラートが出た場合は、ホバー表示される javadoc を見れば何とかなると思います(参考記事)。
4-1. Spring Boot 3.3.2 の場合
ファイルをダブルクリックで開いて、次のようにデータベースのプロパティを書いていきます。
spring.application.name=testApp
spring.datasource.url=jdbc:mysql://localhost:3306/spring_test
spring.datasource.username=yama3
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.sql.init.mode=always
spring.sql.init.schema-locations=classpath:schema.sql
spring.sql.init.data-locations=classpath:data.sql
各項目の意味は、次のとおりです。
項目 | 記載内容 | 備考 |
---|---|---|
spring.application.name | testApp | プロジェクト作成時に指定した名前で自動生成されているはずです |
spring.datasource.url | jdbc:mysql://localhost:3306/[データベース名] | MySQLへのコネクション(3306はポート番号) |
spring.datasource.username | [ユーザー名] | MySQLで作成したユーザー名 |
spring.datasource.password | [パスワード] | MySQLで設定したパスワード |
spring.datasource.driver-class-name | com.mysql.cj.jdbc.Driver | JDBCドライバを指定 |
spring.sql.init.mode | always(実行する)/never(実行しない) | DBの初期化の要否を設定 |
spring.sql.init.schema-locations | classpath:[スキーマSQL文を記載したファイル名] | データベースの初期スキーマを記述したファイル(及びディレクトリ)を指定 |
spring.sql.init.data-locations | classpath:[初期データSQL文を記載したファイル名] | データベースの初期データを記述したファイル(及びディレクトリ)を指定 |
基本的には定型で書けばよく、データベース名、ユーザー名、パスワードを指定するくらいで済みます。
定型ではあるものの、以下の2つの項目は、意味合いを押さえておいた方が良いです。
4-1-1. spring.sql.init.mode
spring.sql.init.mode
は、サーバを起動したときに、schema.sql
、data.sql
に記載したSQL文の内容を実行するかを指定します。
設定値には、以下の2つが紹介されています(参考)。
設定値 | 内容 |
---|---|
always | 常にSQL文が実行されます。既に同名のテーブルがあるのにCREATE TABLE文を実行するとエラーが出るので注意が必要です(後述) |
never | SQL文を実行しません(既にMySQLに必要なテーブルとデータが準備されていればnever の設定でよい) |
4-1-2. spring.sql.init.schema-locations 及び spring.sql.init.data-locations
この項目には、サーバ起動時に実行するSQL文を記載したファイル名を指定します。
ファイル名の前にclasspath:
が必要です。
下図ように、src/main/resources/
の直下にSQLファイルを置く場合は、classpath:schema.sql というように単にファイル名を記載します(なお、この配置はデフォルトのため、記述を行ごと省略しても同じ指定をしたことになります)。
また、次のように、src/main/resources/
の下にフォルダを作成した上でSQLファイルを格納している場合は、classpath:sqlfolder/schema.sql のように、フォルダ名を付けて記載します。
ここでは、データベースの設定のみを書きましたが、application.properties には、その他様々な設定が記述できます。
詳しくは、アプリケーションプロパティ設定一覧などを参照してください。
4-2. Spring Boot 2.4.4 の場合
Spring Boot 2.4.4 については、ここをクリック
ファイルをダブルクリックで開いて、次のようにデータベースのプロパティを書いていきます。
spring.datasource.url=jdbc:mysql://localhost:3306/spring_test
spring.datasource.username=yama3
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.initialization-mode=always
spring.datasource.schema=classpath:schema.sql
spring.datasource.data=classpath:data.sql
spring.datasource.sql-script-encoding=utf-8
各項目の意味は、次のとおりです。
項目 | 記載内容 | 備考 |
---|---|---|
spring.datasource.url | jdbc:mysql://localhost:3306/[データベース名] | MySQLへのコネクション(3306はポート番号) |
spring.datasource.username | [ユーザー名] | MySQLで作成したユーザー名 |
spring.datasource.password | [パスワード] | MySQLで設定したパスワード |
spring.datasource.driver-class-name | com.mysql.cj.jdbc.Driver | JDBCドライバを指定 |
spring.datasource.initialization-mode | always(実行する)/embedded(埋め込みDBのときに実行)/never(実行しない) | DBの初期化の要否を設定 |
spring.datasource.schema | classpath:[スキーマSQL文を記載したファイル名] | データベースの初期スキーマを記述したファイル(及びディレクトリ)を指定 |
spring.datasource.data | classpath:[初期データSQL文を記載したファイル名] | データベースの初期データを記述したファイル(及びディレクトリ)を指定 |
spring.datasource.sql-script-encoding | utf-8 など | 文字コードを指定(何の?) |
基本的には定型で書けばよく、データベース名、ユーザー名、パスワードを指定するくらいで済みます。
定型ではあるものの、以下の2つの項目は、意味合いを押さえておいた方が良いです。
initialization-mode
spring.datasource.initialization-mode
は、サーバを起動したときに、schema.sql
、data.sql
に記載したSQL文の内容を実行するかを指定します。
設定値には、以下の3つがあります。
設定値 | 内容 |
---|---|
always | 常にSQL文が実行されます。既に同名のテーブルがあるのにCREATE TABLE文を実行するとエラーが出るので注意が必要です(後述) |
embedded | 埋め込みDB(H2 Databaseなど)のときにのみSQL文を実行します |
never | SQL文を実行しません(既にMySQLに必要なテーブルとデータが準備されていればnever の設定でよい) |
spring.datasource.schema 及び spring.datasource.data
この項目には、サーバ起動時に実行するSQL文を記載したファイル名を指定します。
ファイル名の前にclasspath:
が必要です。
下図ように、src/main/resources/
の直下にSQLファイルを置く場合は、classpath:schema.sql というように単にファイル名を記載します。
また、次のように、src/main/resources/
の下にフォルダを作成した上でSQLファイルを格納している場合は、classpath:sqlfolder/schema.sql のように、フォルダ名を付けて記載します。
ここでは、データベースの設定のみを書きましたが、application.properties には、その他様々な設定が記述できます。
詳しくは、アプリケーションプロパティ設定一覧などを参照してください。
4-3. Spring Boot 2.5.0 の場合
Spring Boot 2.5.0 の場合については、ここをクリック
Spring Boot 2.5.0 の場合は、次のように記載します。
spring.datasource.url=jdbc:mysql://localhost:3306/spring_test
spring.datasource.username=yama3
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.sql.init.enabled=true
spring.sql.init.schema-locations=classpath:schema.sql
spring.sql.init.data-locations=classpath:data.sql
spring.sql.init.encoding=utf-8
2.4.4 と異なる項目を一覧にすると、次のとおりです。
項目 | 備考 |
---|---|
spring.sql.init.enabled | DBの初期化の要否を設定(true=実行する、false=実行しない) |
spring.sql.init.schema-locations | DBの初期スキーマを記述したファイルを指定 |
spring.sql.init.data-locations | DBの初期データを記述したファイルを指定 |
spring.sql.init.encoding | 文字コードを指定 |
spring.sql.init.enabled
は true(初期化を実行する) または false(初期化を実行しない)で指定します。
デフォルトが true なので、何も記載しなければ true の設定となります。
4-4. Spring Boot 2.5.1 の場合
Spring Boot 2.5.1 については、ここをクリック
Spring Boot Version 2.5.1 では spring.sql.init.enabled
は非推奨とされていたため、このバージョンを選んだ場合は、次のように書いておきます。
spring.datasource.url=jdbc:mysql://localhost:3306/spring_security_test
spring.datasource.username=yama3
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.sql.init.mode=always
spring.sql.init.schema-locations=classpath:schema.sql
spring.sql.init.data-locations=classpath:data.sql
spring.sql.init.encoding=utf-8
項目 | 記載内容 |
---|---|
spring.sql.init.mode | DBの初期化の要否を設定(always=実行する、embedded=埋め込みDBのときに実行、never=実行しない) |
5. 作成するファイルと配置するディレクトリ
今回のサンプルプロジェクトでは、次の4つのファイルを追加します。
ファイル名 | 内容 |
---|---|
TestController.java | コントローラの内容を記載 |
index.html | ビューの内容を記載 |
schema.sql | サーバ起動時に実行するSQL文を記載(テーブル定義など) |
data.sql | サーバ起動時に実行するSQL文を記載(初期データなど) |
以下、1つずつファイルを作っていきます。
6. SQLファイルの作成
SQLファイルには、プロジェクト起動時に実行されるSQL文を記載します。
なお、データベース上に、既に必要なテーブルとデータがあれば、これらの2つのファイルを作成しなくともアプリケーションは起動できます(その場合には、application.properties の設定が少し変わります)。
schema.sqlの作成
まず、ファイルを追加していきます。
Package Explorer上のsrc/main/resources
を右クリックして、「New」→「Other」を選択します。
最後に、ファイル名を「schema.sql」として、Finish をクリックします。
<SQLファイルの開き方>
SQLファイルについては、ファイル名を右クリックして、「Open With」→「Text Editor」で開きます。
ダブルクリックで開こうとすると、自身のPCに設定してある標準のエディターで開いてしまい面倒だからです。
schema.sql には、次のように、CREATE TABLE文などを記載します。
DROP TABLE IF EXISTS test_table;
CREATE TABLE test_table
(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(100),
old INT,
PRIMARY KEY(id)
);
CREATE TABLE文(テーブル作成のSQL文)だけでも良いのですが、作成したテーブルが残ったままだと2回目以降にサーバを起動したときに「同名のテーブルは作れない」旨のエラーが出てしまいます。
そのため、最初に DROP TABLE文(テーブル削除のSQL文)を置いています(IF EXISTS のところで「テーブルが存在していたら削除する」という指定にしています)。
<参考記事>
SpringBootのDB初期化方法
data.sqlの作成
ファイルの追加方法は、schema.sql と同様で、ファイル名は「data.sql」とします。
data.sql には INSERT INTO文(データを追加するSQL文)などを記載して、初期データを入れるようにします。
INSERT INTO test_table(name, old)
VALUES('Taro', 30), ('Jiro', 25), ('Saburo', 22);
7. コントローラーの作成
次にコントローラーの作成です。
ここでは、コントローラーとして TestController.java ファイルを作成します。
まず、Package Explorer 上のcom/example/demo
を右クリックして、「New」→「Class」を選択します(SQLファイルと同様なので画像は省略)。
すると、次の画面が表示されますので、Name(クラス名)を「TestController」として Finish をクリックしてファイルを作成します。
ファイルはダブルクリックで開きます。
コントローラーに記述するソースコードは次のとおりです。
package com.example.demo;
import java.util.List;
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;
@Controller
@RequestMapping()
public class TestController {
@Autowired
private JdbcTemplate jdbcTemplate;
@GetMapping("/index")
public String index(Model model) {
String sql = "SELECT * FROM test_table";
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
model.addAttribute("testList", list);
return "index";
}
}
import文が多くて、無駄に長く見えますが、Ctrl+Shift+O で自動で補完できるので、あまり気にしないでください。
単純な構成にするため、Service や Repository などのクラスは作成していません。
以下、簡単な説明をしますが、書いてあることは「Spring徹底入門」という書籍を 適当にかいつまんで勝手に解釈している ぐらいのものですので、正確性は保証できません。
ただ、何となくのイメージが伝われば幸いという気持ちで書いておきます。
@Controller
まず、冒頭の部分から見ていきます。
@Controller
// (略)
public class TestController {
// (略)
}
コードの最初に @Controller というアノテーションを付けています。
アノテーションとは注釈の意味ですが、Springにおいては、@Controller の記述をすることでそのクラスがコントローラーとして認識される仕様になっています。
正しくは、「コンポーネントスキャンによりDIコンテナに登録される」という言い回しがされていますが、とりあえずは「コントローラーの役割を示す記述」と考えておけば大丈夫でしょう。
@RequestMapping 及び @GetMapping
次に、@RequestMapping 及び @GetMapping の記述についてです。
この記述により、WEBアプリケーションのリクエストパスが指定されています。
@RequestMapping()
public class TestController {
// (略)
@GetMapping("/index")
public String index(Model model) {
// (略)
}
}
クラスレベルに指定している @RequestMapping() は、ベースパスを表しています(これは @RequestMapping("/") と書いても同じです)。
ローカルホストではhttp://localhost:8080/
というパスが該当します。
メソッドレベルに指定している @GetMapping("/index") は、ベースパスからの相対パスを表してます。
これをローカルホストに当てはめればhttp://localhost:8080/index
というパスになります。
このパスにアクセスすると、直下にある indexメソッドに処理が渡されるということになります。
なお、@GetMapping は HTTP通信の GET メソッドであることも表しています。
念のため、もう1つ例を見ておきます。
次のような組合せだと、@PostMapping("/index") によるリクエストパスはhttp://localhost:8080/home/index
となります。
@RequestMapping("/home")
// (略)
@PostMapping("/index")
}
言うまでもないですが、@PostMappingはHTTP通信の POSTメソッドであることも表しています。
@Autowired 及び JdbcTemplate
今度は、次の記述についてです。
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired は、「型による解決(By Type)で自動的にDIコンテナにインジェクションするもの」というような説明がされています(初心者にとっては、なんのこっちゃです)。
JdbcTemplate は、データベースへのアクセスを容易にするためのクラスです。これはどんな言語にも同様のライブラリがあるので、イメージは湧くのではないかと思います。
結論として、上記の2行さえ書けば、面倒な設定をすることなく「データソースの初期化が完了した JdbcTemplate クラスを利用することができる」ということになります。
先に、application.properties というファイルで設定した接続情報なども自動的に付加されていると考えれば、何となく役割が分かる気になります(ちょっと違うかもですが)。
Model
さて、次に Model です。
いわゆる MVC(Model-View-Controller)の最初に出てくる Model に当たるものです。
indexメソッドの引数に、突然現れています。
public String index(Model model) {
// (略)
}
Ruby on Rails などのフレームワークにおいては、Model というファイル(クラス)が存在するので分かりやすいのですが、Spring MVC の Model は一体どこからやってくるのか謎な感じがします。
解説によれば、Spring MVC の Model は「デフォルトでサポートされている型で、遷移先に連携するデータを保持したり返却したりするもの」というような説明がされています(「Spring徹底入門」から適当に意訳)。
いい加減に言ってしまうと、「Modelオブジェクトはメソッドの引数に設定するだけで取得することができ、コントローラーやビューなどの間でデータのやりとりを担っている」というようなイメージです。
とりあえず、上記のように引数に設定することで、Model を使うことができます。
indexメソッド
最後に、indexメソッドの中身を1行ずつ見ていきます。
① SQL文の作成
String sql = "SELECT * FROM test_table";
メソッド内の最初の1行は、test_table の全てのレコードを取得するSQL文です。
② SQL文の実行
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
この1文で、変数list
にSQL文で取得したデータが代入されます。
左辺のList<Map<String, Object>>
は、Map(連想配列のようなもの)を要素に持つ List 型を表しています。
1つのMap<String, Object>
に,、{ id=1, name="Taro", old=30 }というようなレコードが1つ格納され、これを List にして全レコードを取得できる型にしています(詳しくは、この記事を参照)。
右辺は、JdbcTemplate の queryForList メソッドを使用してSQL文を実行しています。戻り値の型はList<Map<String, Object>>
となります。
なお、1レコードのみ取得するSQL文の場合は、queryForMap メソッドを使用します。この場合の戻り値の型はMap<String, Object>
となります。
③ Modelにオブジェクトを追加
model.addAttribute("testList", list);
この1文で、Model オブジェクトの addAttributeメソッドを使用して、Model にlist
オブジェクトを追加しています。
その際に、list
オブジェクトの名前として"testList"
と指定しています。
Model に追加した内容は、後述の ビュー(HTMLファイル) において使用されます。
④ Viewファイルの指定
return "index";
最後のreturn
で文字列 "index" を返しています。
この戻り値で、使用する Viewファイル名(index.html)が指定されることになります。
サンプルコードの場合、index.html の格納場所が、src/main/resources/templates
の直下であるためreturn "index";
という記述になっていますが、例えば home というフォルダを作成してその中に index.html を格納している場合は、フォルダ名も含めて、return "home/index";
という記述をすることになります。
8. ビューの作成
まず、Package Explorer上のtemplates
を右クリックして、「New」→「Other」を選択します。
最後に、ファイル名を「index.html」として、Finish をクリックします。
生成された index.html ファイルをダブルクリックで開いて、次のように編集します。
テンプレートエンジンに thymeleaf(タイムリーフ) を使用して変数などを埋め込んでいます。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<table>
<tr>
<th>id</th>
<th>name</th>
<th>old</th>
</tr>
<tr th:each="test : ${testList}">
<td th:text="${test.id}"></td>
<td th:text="${test.name}"></td>
<td th:text="${test.old}"></td>
</tr>
</table>
</body>
</html>
以下、イメージを掴むために、簡単な説明をしておきます。
Thymeleaf の名前空間の宣言
<html xmlns:th="http://www.thymeleaf.org">
上記の xmlns 宣言によりThymeleaf(http://www.thymeleaf.org
)の名前空間(th
)を定義しています。
この宣言することで「Thymeleaf が使用できる」ということになります。
ところが、この宣言がなくても普通に Thymeleaf が使えてしまいます(裏側で色々と設定されているんでしょうね…)。
なお、この宣言がないとSTS(IDE)で警告が出されたりするので、素直に定義しておくべきでしょう。
<参考サイト>
・テンプレートエンジン(Thymeleaf)
th:text
th:text はタグ内のテキストを出力するために使用します。
簡単な例を書くと、次のとおりです。
<h1 th:text="Hello World!">hoge</h1>
上記のHTML文では、Hello World!
というテキストが表示されます(hoge
が書き換えられます)。
そして、次のように、表示するテキストを変数で指定すると、タグ内のテキストを動的に埋め込むことができます。
<h1 th:text="${title}"></h1>
変数は、${変数名}
という形で指定します。
この変数は、Modelから取り出すことになります。
th:each
次のように th:each を使用すると繰り返し処理をすることができます。
<tr th:each="test : ${testList}">
<td th:text="${test.id}"></td>
<td th:text="${test.name}"></td>
<td th:text="${test.old}"></td>
</tr>
このコードを見るだけでも、何となく for each 文の形式になっていることが分かります。
つまり、 testList というリストの要素を1つずつ変数 test に代入して、その test からtest.id
、test.name
、test.old
という値を取り出しているということになります。
なお、この testList というリストは、先述の「③ Modelにオブジェクトを追加」というところで、コントローラー側で作成した List を Model に追加したものです(以下の1文です)。
model.addAttribute("testList", list);
Thymeleaf の詳細については、以下の記事などが参考になります。
<参考記事>
・Spring Boot で Thymeleaf 使い方メモ
・Thymeleafチートシート
9. アプリケーションの起動
Package Explorer上のプロジェクト名(ここではTestApp
)を右クリックして、「Run As」→「Spring Boot App」を選択します。
(Mavenの場合も同様に「Run As」→「Spring Boot App」を選択します。)
実行すると、STS の Console 画面に次のように文字列が表示されていき、アプリケーションが起動します。
アプリケーションが起動したら、ブラウザから http://localhost:8080/index にアクセスします。
次のように表示されれば成功です。
以上で、何となくですが、Spring MVC のデータの流れは見えてくるのではないかと思います。
さいごに
どんなことでも、最初はさっぱり分かりません。
私も、Spring Boot は始めたばかりですが、これから始める方のために、何らかのとっかかりとなればという意図で、記事として残させていただきました。
参考となるサイトも、なるべくリンクを残しましたので、お役に立てれば幸いです。