Webアプリケーション入門

目次

1. Webアプリケーションとは.. 3

2 フレームワーク.. 3

2.1 利点.. 4

2.2 選択.. 4

3. Spring Boot 4

3.1 Spring framework. 4

3.2 Spring Boot 5

3.3 プログラミング言語.. 5

3.4 開発環境.. 5

3.5 Spring Initializr 5

4 簡単なWebアプリケーション.. 6

4.1 (手順1)初期プロジェクトを作成.. 6

4.2 (手順2)初期プロジェクトをダウンロード.. 7

4.3 (手順3)初期プロジェクトをEclipseにインポート.. 8

4.4 (手順4)初期プロジェクトをカスタマイス.. 10

4.4.1 カスタマイズの場所.. 11

4.4.2 カスタマイズの内容.. 11

4.5 Webアプリケーションを起動.. 13

4.6 結果を確認.. 14

4.7 Webアプリケーションを停止.. 14

5. Webアプリケーションの設計と構造.. 14

5.1 アプリケーションアーキテクチャ.. 15

5.2 MVC(Model View Controller.. 16

5.3 レイヤードアーキテクチャ.. 16

5.4 クリーンアーキテクチャ.. 16

6. Javaパッケージ構成の例.. 17

6.1 層型アーキテクチャ.. 17

6.2 レイヤードアーキテクチャ的な例.. 17

6.3 クリーンアーキテクチャ的な例.. 17

7 取引銀行管理システム(サンプルアプリ).. 18

7.1 アプリケーションの要件.. 18

7.2 ユースケ―ス.. 19

7.3 プロジェクト作成時の手順.. 19

7.3.1 Initializrで初期プロジェクトを作成.. 20

7.3.2 GitHubでリポジトリ mainbank を作成(任意:必要な方のみ).. 20

7.4 ドメインモデルと永続化(継承の永続化戦略).. 25

8. Spring依存性注入とは.. 30

8.1 DIの基本的な考え方.. 30

8.2 DIの例.. 30

8.3 DIの仕組み.. 31

8.4 DIのメリット.. 32

8.5 依存性とは.. 32

8.6 注入とは.. 32

9. Springアノテーション.. 32

9.1 主要なアノテーション.. 32

9.2 インスタンス化対象を指定.. 37

9.3 バリデーション関係.. 38

10 コントローラとビューの間のデータの受け渡し.. 38

10.1 View → Controller 38

10.1.1 補足説明.. 40

10.2 Controller → View. 40

11. Springアスペクト指向プログラミング.. 41

11.1 構成要素.. 41

11.1.1 アスペクト(Aspect.. 41

11.1.2 アドバイス(Advice.. 41

11.1.3 ジョインポイント(Join Point.. 41

11.1.4 ポイントカット(Pointcut.. 41

11.1.5 ターゲット(Target.. 41

11.2 簡単な例.. 41

12. Spring JPA 永続化.. 43

12.1 エンティティオブジェクトの状態遷移.. 43

12.2 エンティティオブジェクトの状態.. 43

12.3 トランザクション境界での状態遷移の挙動.. 44

13. MySQL. 44

13.1 データベースの作成.. 45

13.2 ユーザとパスワードの作成.. 46

13.2.1 usernameとpassword の確認方法と設定方法.. 46

13.3 application.propertiesの設定.. 46

13.4 データベースとスキーマ.. 47

13.5 spring.jpa.hibernate.ddl-autoの設定.. 47

13.5.1 代表的なオプション.. 47

13.5.2 オプションのまとめ.. 48

14. Tipsレンダリング.. 48

14.1 サーバサイドレンダリング(Server-Side Rendering, SSR.. 48

14.2 クライアントサイドレンダリング(Client-Side Rendering, CSR.. 49

14.3 静的サイト生成(Static Site Generation, SSG.. 49

15. Tips:セレクトボックスの書き方.. 49

 

 

1. Webアプリケーションとは

Webアプリケーション(Web ApplicationWeb App)とは、インターネットを介して、Webブラウザ上で動作するアプリケーションのことです。

 

例 マイナポータル(行政手続のオンライン窓口)

 

 

2. フレームワーク

マイナポータルなど、さまざまなWebアプリケーションが存在しますが、それらがゼロから全て開発されているわけではありません。通常、フレームワークと呼ばれるソフトウェアを基盤として開発が行われます。Webアプリケーション用フレームワークとは、多くのWebアプリケーションで共通して利用できる構造や基本的な機能を提供する枠組みです。

フレームワークには、PHP用、Ruby用、そしてJava用のものがあり、Javaでは特にSpringが広く使われています。なお、同じプログラミング言語でも複数のフレームワークが存在します。多くのフレームワークは、オープンソースソフトウェアとして無料で利用することが可能です。

フレームワークを使うことで、開発者は基礎的な部分を一から作る手間を省き、アプリケーションの本質的な機能の開発に集中することができます。

 

2.1 利点

フレームワークを使用すると次のような利点があります。

(1) 再利用できる部品を提供します

フレームワークには、よく使われる機能やパターン(ユーザー認証、データベース接続、ページ遷移など)が組み込まれています。それを利用することで、毎回ゼロからコードを書く必要がありません。

 

(2) 標準的な構造を提供します

フレームワークは、アプリケーションの構造や作り方にある程度のルールを提供します。このため、どの開発者も一貫した方法でコードを書くことができ、チームでの開発が容易になります。

 

(3) セキュリティやパフォーマンスを向上できます

フレームワークには、セキュリティやパフォーマンスに関する考慮がされており、これを利用することでセキュアで効率的なWebアプリケーションを作ることができます。

 

2.2 選択

Webアプリケーションを作成する際には、何らかのフレームワークを使用することが一般的です。フレームワークは、使用するプログラミング言語によって選択肢が決まってきます。

Java言語用としては、本書で紹介する Spring の他にも Apache Struts などがあります。

Python 用の場合は、Django FlaskPHP 用の場合は、LaravelCakePHPRuby 用の場合は、Ruby on RailsC#の場合は、ASP.NET Core Blazor などがあります。

 

3. Spring Boot

Spring Boot Spring フレームワークの一部分(サブセット)です。Spring Bootについて説明する前に、Springについて説明します。

 

3.1 Spring framework

Spring framework(以降 Spring と略称します)は、Javaでエンタープライズアプリケーションを開発するためのフレームワークです。主な特徴は、依存性注入(DI)やアスペクト指向プログラミング(AOP)などを使って、柔軟でスケーラブルなアプリケーションを構築しやすくする点です。Springを使うと、ビジネスロジックに集中しやすくなります。

一方で、Springは多くの機能を有するフレームワークであるため、どの機能を選択し使用すればよいのか戸惑うこともありました。そこでこの問題を解消するために登場したのが Spring Boot です。

 

3.2 Spring Boot

Spring Bootは、Springをより簡単に使えるようにしたフレームワークです。自動設定機能や組み込みWebサーバー(Tomcatなど)が提供されているため、設定が少なく、すぐにアプリケーションを起動できるのが特徴です。スムーズにSpringのプロジェクトを始められる点がSpring Bootの大きなメリットです。

 

3.3 プログラミング言語

Spring フレームワークは、主に Java をサポートしていますが、他の複数のプログラミング言語も利用可能です。

以下の言語が Spring フレームワークおよび Spring Boot でサポートされています:

·     Java

Spring は元々 Java のために設計されたフレームワークであり、Java が主な言語です。

·     Kotlin

Spring フレームワークおよび Spring Boot では、Kotlin も公式にサポートされています。

·     Groovy

Groovy は、動的言語でありながら JVM 上で動作するスクリプト言語です。

 

これらの言語はすべて Spring Boot でも同様にサポートされており、Java プロジェクトと同じように、Kotlin Groovy Spring Boot アプリケーションを構築することができます。

例えば、Spring Initializr(後述)を使って、Kotlin Groovy ベースの Spring Boot プロジェクトを作成することも可能です。

 

3.4 開発環境

本書では、統合開発環境(IDE)として「Pleiades All in One」(以降Eclipseと記載)を使用します。

(参考)

もし、Java言語やIDEに関する情報が必要でしたら

Javaプログラミング入門」の「1. 学習環境を準備します」を参考ください。

http://www.fk-nextdesign.sakura.ne.jp/learn/Roadmap.html

 

3.5 Spring Initializr

本書ではSpringの初期プロジェクト(IDEにインポート可能な空のSpringアプリケーションプロジェクト)を作成するために、「Spring Initialzr」を利用します。

Spring Bootは、Springを使いやすくしましたが、それでも、最初に Spring Boot用のJavaプロジェクトを構成するときはボタンひとつでは済みません。そこでWeb画面から構成できるようにしたのが、Spring Initialzrです。この初期プロジェクトをEclipseにインポートして、独自のプログラムを追加・編集することで、自前のWebアプリケーションとして作成します。具体的な操作は後述します。

 

4. 簡単なWebアプリケーション

Eclipseを使ってJava Spring Webアプリケーションを作成するためには、まずEclipse上に新しいプロジェクトを作成します。方法はいくつかありますが、本書では次の手順で作成します。

 

4.1 (手順1)初期プロジェクトを作成

(1) Spring initializrにアクセスします

https://start.spring.io/

 

(2) 次図のように設定します

本サンプルでは Maven を選択しますが、他でも問題ありません。

Dependencies(依存性)は次の3つを選択します。

右上の「ADD …」ボタンを押下してDependencyを選択し追加します。

·     Spring Web
·     Thymeleaf
·     Spring Boot DevTool

 

上の構成は、Thyemleafを使う場合の最小構成です。

もし、永続化(データベース)を使用するような場合は、次の依存性が必要です。

この依存性の構成は一例です。例えば、MySQLを使用したい場合は別の構成になります。

 

·     Spring Web
·     Spring Data JPA
·     PostgreSQL Driver
·     H2 Database
·     Thymeleaf
·     Spring Boot DevTool

 

 

 

 

4.2 (手順2)初期プロジェクトをダウンロード

適切なフォルダに保存し、展開します。

このフォルダはEclipseプロジェクトの保管場所になります。

 

ダウンロードし展開後の内容

C:.

  .gitignore

  HELP.md

  mvnw

  mvnw.cmd

  pom.xml

├─.mvn

  └─wrapper

          maven-wrapper.properties

└─src

    ├─main

      ├─java

        └─com

            └─example

                └─hello

                        HelloApplication.java

     

      └─resources

            application.properties

         

          ├─static

          └─templates

    └─test

        └─java

            └─com

                └─example

                    └─hello

                            HelloApplicationTests.java

 

 

4.3 (手順3)初期プロジェクトをEclipseにインポート

Eclipseで、ファイル → インポート → 既存 Maven プロジェクト →

 

 

 

 

完了

 

4.4 (手順4)初期プロジェクトをカスタマイス

初期プロジェクトのままではHelloWorldページは表示されませんので、次の4つのファイルを追加します。

HelloControllerjava

HelloWorld.html

error.html

index.html

 

追加する場所は次図の通りです。

4.4.1 カスタマイズの場所

 

4.4.2 カスタマイズの内容

(1) HelloControllerjava

package com.example.hello;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.servlet.ModelAndView;

@Controller

public class HelloController {

 

           @GetMapping("hello")

           public ModelAndView hello(ModelAndView mav) {

                      mav.setViewName("HelloWorld");

                      return mav;

           }

}

 

(2) HelloWorld.html

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

</head>

<body>

<h1>HelloWorld !!</h1>

</body>

</html>

 

(3) error.html

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

</head>

<body>

<h1>エラーページ</h1>

</body>

</html>

 

(4) index.html

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

</head>

<body>

<h1>静的index.htmlページ</h1>

</body>

</html>

 

 

4.5 Webアプリケーションを起動

Eclipseのパッケージエクスプローラまたはプロジェクトエクスプローラで hello を右クリックします。

次図のように

 

Eclipseのコンソールに次のようなログが表示され、Webアプリケーションが起動したことを確認できます。

 

4.6 結果を確認

ブラウザを開いて次のURLにアクセスします。

http://localhost:8080/

http://localhost:8080/hello

http://localhost:8080/hello999

 

4.7 Webアプリケーションを停止

いくつか方法があります。一つは次図の赤いボタン押下で停止します。

 

5. Webアプリケーションの設計と構造

前章の「簡単なWebアプリケーション」(Spring + Thymeleaf) では,最小限のリクエストとレスポンスを確認できました。しかし、ここから先を、自己流だけで機能を追加していっても、実用的な品質のアプリケーションを作成することは困難でしょう。通常は、すでに多くの開発者によって使用されている設計手法や構造パターンを参考にして設計や構造を決めていきます。

 

次の一文は、エリックエヴァンスのドメイン駆動設計 日本語版第4章から引用したものです。

~引用ここから~

輸送アプリケーションで、貨物の荷出し地を都市の一覧から選択するという、ユーザの簡単な操作をサポートしたい。そのためには、次の処理を実行するプログラムコードがなければならない。①スクリーンにウィジェットを描き、②選択できる都市をすべてデータベースに問い合わせて、③ユーザーの入力を解釈して検証し、④選択された都市を貨物と結び付け、⑤データベースへの変更をコミットする。このコードすべてが同じプログラムの一部になるが、輸送業というビジネスに関係するのは、そのごく一部にすぎない。

ソフトウェアプログラムには、さまざまな種類のタスクを実行する設計とコードがある。

ユーザ入力を受つけ、ビジネスロジックを実行し、データベースにアクセスして、ネットワークを通じて通信し、ユーザに情報を表示するといった具合である。したがって、各プログラム機能に含まれるコードは、かなりの量になる可能性がある。

~引用ここまで~

 

単純なプログラムですが、十分な分析や設計をしないで、HelloWorldの延長のようなつもりで作成すると複雑で混沌としたWebアプリケーションになるでしょう。当然、拡張性や保守性の低いシステムとなります。

そのためにはアプリケーションアーキテクチャというものを理解し適切に使用していく必要があります。

 

以下の用語は、すべてWebアプリケーションの設計や構造に関するものであり、互いに関連しています。それぞれが異なる視点からアプリケーションの構造を示していますが、目的は一貫して、コードの可読性や保守性、拡張性を高めることです。

 

5.1 アプリケーションアーキテクチャ

アプリケーションアーキテクチャとは、ソフトウェア全体の構造を定義し、どのように機能が分割されているか、各コンポーネントがどのように相互作用するかを示します。Webアプリケーションでは、複雑な要件を効率よく満たすために、設計時に適切なアーキテクチャが選ばれます。以下に説明するMVC、レイヤードアーキテクチャ、クリーンアーキテクチャはすべて、異なる種類のアプリケーションアーキテクチャです。

 

5.2 MVCModel View Controller

MVCは、Webアプリケーションの構造を「Model(データの管理)」「View(ユーザーインターフェース)」「Controller(ロジックと指令)」の3つに分ける設計パターンです。

·     Model: データやビジネスロジックを担当します。データベースの操作やデータの整形などを行います。
·     View: ユーザーに表示する部分です。HTMLやテンプレートエンジンなどで、ユーザーインターフェースを生成します。
·     Controller: ユーザーの入力を受け取り、ModelViewを制御します。ユーザーからのリクエストを処理し、適切なレスポンスを返す役割を担います。

 

5.3 レイヤードアーキテクチャ

レイヤードアーキテクチャは、アプリケーションを層(レイヤー)ごとに分割する設計です。一般的には、以下のような層に分けられます:

·     プレゼンテーション層: ユーザーインターフェースを扱います(HTMLCSSJavaScriptなど)。
·     アプリケーション層: ビジネスロジックを実行し、アプリケーションの操作を管理します。
·     ドメイン層: ビジネスルールやデータの処理を担当します。
·     データアクセス層: データベースとのやり取りを行います。

このように層を分けることで、責任の分離が明確になり、保守や拡張がしやすくなります。

 

5.4 クリーンアーキテクチャ

クリーンアーキテクチャは、アプリケーションを柔軟かつ保守しやすくすることを目指した設計思想です。ソフトウェアの依存関係が一方向(内側から外側)になるように設計します。基本的な構造は以下の通りです:

·     エンティティ: ビジネスルールやデータモデルを表現します。
·     ユースケース: システムがユーザーに提供するサービスや機能です。
·     インターフェース(外側の層): プレゼンテーション層やデータベース層といった、システム外部とやり取りする部分です。

クリーンアーキテクチャの特徴は、外部依存(データベース、UI、フレームワークなど)からビジネスロジックを分離することにより、変更に強い設計を実現する点です。

重要な関連概念

·     SOLID原則: オブジェクト指向設計の基本的な5つの原則で、保守性や拡張性を高めるためのガイドラインです。
·     依存性の逆転: クリーンアーキテクチャで重要な概念であり、具体的な実装がビジネスロジックに依存するのではなく、ビジネスロジックがインターフェースに依存するという考え方です。
·     依存性注入(DI: アプリケーションの依存関係を外部から注入することで、モジュール間の結合を緩める設計手法です。Springフレームワークなどでよく使われます。

これらの概念は、Webアプリケーション開発におけるコードの可読性、テストのしやすさ、保守性を向上させるために非常に役立ちます。

 

6. Javaパッケージ構成の例

本章の内容は例です。

 

6.1 層型アーキテクチャ

層毎に役割を明確に分けます。トランザクション・スクリプトと呼ばれるアンチパターンとならないように、そして、低品質で保守や拡張が困難な混沌としたソフトウェアとならないように、適切に役割を分けます。

各層の名前や構成はチームで決めていきます。必要な場合はリファクタリングします。

名前

役割

プレゼンテーション層

アクター(人間や別のコンピュータ)と情報を相互通信します。

アプリケーション層

ユースケ―ス、シナリオを実行します。

ドメイン層

ドメイン駆動設計などでモデリングしたクラス群によってドメインロジックを提供します。

インフラストラクチャ層

上位のレイヤを支える一般的な技術機能(永続化機能やデータ送受信機能など)を提供します。

 

6.2 レイヤードアーキテクチャ的な例

├─java

  └─com

      └─example

          └─mainbank

              ├─presen (プレゼンテーション層(コントローラー、ビュー))

              ├─appl (アプリケーション層(ユースケース、サービス))

              ├─config

              ├─domain

              └─infra (infrastructure)

└─resources

    ├─static

      └─css

    └─templates

 

6.3 クリーンアーキテクチャ的な例

クリーンアーキテクチャでは、依存関係の方向を意識し、ビジネスロジックを中心に据えるような構成が推奨されます。

├─java

  └─com

      └─example

          └─mainbank

              ├─config

              ├─domain

                ├─model

                └─repository (repository interface)

              ├─application

                └─usecase (business logic)

              ├─infra (implementation of repository, external services, etc.)

              ├─adapter (controllers, gateways, and presenters)

              └─shared (common utilities)

└─resources

    ├─static

    └─templates

 

 

 

7. 取引銀行管理システム(サンプルアプリ)

7.1 アプリケーションの要件

自社が取引する銀行の情報を管理する。

【銀行の種類】

   ・都市銀行

   ・地方銀行

   ・ネット銀行

【取引の種類】

  ・融資 (Loan)

  ・預金 (Deposit)

  ・送金

 

7.2 ユースケ―ス

1

ユースケース名

取引銀行を登録する。

 

アクター

経理部員。

 

事前条件

登録する取引銀行は未登録であること。

 

事後条件

エラーなしの場合は、登録済みとなること。

エラーありの場合は、未登録のままであること。

 

主シナリオ

1. ブラウザから所定のURLにアクセスし、取引銀行一覧画面を開く。

2. 新規登録ボタンを押下して新規登録画面を開く。

3. 取引銀行名、銀行種類、取引種類を入力する。

4. 保存ボタンを押下する。

 

副シナリオ

保存ボタン押下でエラーメッセージが表示された場合

 

 

エラーを修正し、再度保存ボタンを押下する。

または、キャンセルボタン押下で終了する。

 

7.3 プロジェクト作成時の手順

サンプルアプリ作成時のInitializrの設定内容とGitHubで管理する手順について説明します。

 

7.3.1 Initializrで初期プロジェクトを作成

 

7.3.2 GitHubでリポジトリ mainbank を作成(任意:必要な方のみ)

これはGitHubでソースコードを管理したい場合のみ必要です。後からGitHub管理もできます。

Codeボタンから「Open with GitHub Desktop」を選択すると自分のPCにインストール済みのGitHub Desktopが起動するので、GitHub Desktop を操作して、リポジトリをクローンします。

 

 

GitHub Desktop画面が開きます

Clone すると Local Path のフォルダが自動生成されます。(そのつもりで指定してください)

次のような結果になります。

 

カレントブランチは、デフォルトのmainブランチになっています。

 

この例では、main ブランチから develop ブランチを作成し、develop をカレントブランチにしました。

ローカルフォルダに初期プロジェクトを解凍した後の mainbank を移動(コピー&貼付け)します。

この辺の手順は色々なやり方あると思います。

GitHub Desktopの状態

Commitコメントを入力 → Commit to develop Push origin Create Pull Request

 → ブラウザでGithubページが開く

下の方にスクロールして Create pull request を押下します

少し下にスクロール

Merge pull requestを押下

 

Confirm mergeを押下

Mergedが表示されたらマージ成功です。

 

Eclipseにインポートします。

Eclipse ファイルメニュー → インポート → 既存Mavenプロジェクト → ルートディレクトリとして mainbank フォルダを選択 → 完了。

このインポートは mainbank を解凍し配置した後でも問題ありません。

 

7.4 ドメインモデルと永続化(継承の永続化戦略)

本書ではSpring Boot JPA + MySQLを使用します。MySQLについては後述します。また、取引銀行管理に登場する一部のドメインモデル名を使いますが、本セクションの目的は、継承関連を持つエンティティ(クラス)の永続化戦略です。そのため、エンティティのプロパティや振舞いはほぼ省略しています。

 

(クラス図)

 

Javaコード)

package com.example.mainbank.domain;

import jakarta.persistence.Entity;

import jakarta.persistence.GeneratedValue;

import jakarta.persistence.GenerationType;

import jakarta.persistence.Id;

import jakarta.persistence.Inheritance;

import jakarta.persistence.InheritanceType;

/**

 * エンティの基底クラス

 */

@Entity

@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)

public abstract class BaseEntity {

           @Id

           //@GeneratedValue(strategy=GenerationType.IDENTITY)

           @GeneratedValue(strategy=GenerationType.TABLE)

           protected Long id;

           public Long getId() {

                      return id;

           }

           public void setId(Long id) {

                      this.id = id;

           }

}

 

package com.example.mainbank.domain;

import jakarta.persistence.Entity;

/**

 * 取引銀行

 */

@Entity

public class MainBank extends BaseEntity {      

           private String name;

           //コンストラクタ

           public MainBank() {

                      this.name = "";

           }

}

 


 

MySQLデータベーステーブルの状態)

 

pom.xml

<?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>3.3.4</version>

        <relativePath/> <!-- lookup parent from repository -->

    </parent>

    <groupId>com.example</groupId>

    <artifactId>mainbank</artifactId>

    <version>0.0.1-SNAPSHOT</version>

    <name>mainbank</name>

    <description>Main Bank Management</description>

    <url/>

    <licenses>

        <license/>

    </licenses>

    <developers>

        <developer/>

    </developers>

    <scm>

        <connection/>

        <developerConnection/>

        <tag/>

        <url/>

    </scm>

    <properties>

        <java.version>17</java.version>

    </properties>

    <dependencies>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-data-jpa</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>com.h2database</groupId>

            <artifactId>h2</artifactId>

            <scope>runtime</scope>

        </dependency>

        <dependency>

            <groupId>com.mysql</groupId>

            <artifactId>mysql-connector-j</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>

 

ここまで、クラス毎にテーブルを作成する戦略ですです。

ただし、@GeneratedValue(strategy = GenerationType.IDENTITY)と指定するとエラーになります。

原因は、InheritanceType.TABLE_PER_CLASS GenerationType.IDENTITY の組み合わせにあります。

正しい指定方法は、@GeneratedValue(strategy = GenerationType.TABLE)です。

このように指定することで、Hibernate がテーブル (hibernate_sequences) を作成し、そこから ID を生成するので、TABLE_PER_CLASS と互換性があり、3つのテーブルが正しく作成されます。

この戦略は適切な解決策と言えます。ただし、ID テーブルが追加で作成されることに注意が必要です。

 

この他の戦略としては、

InheritanceType.JOINED InheritanceType.SINGLE_TABLE があります。この戦略も検討可能です。

 

PostgreSQL の場合は、

PostgreSQL IDENTITY 戦略と TABLE_PER_CLASS の組み合わせが MySQL と同様に問題を引き起こす可能性があります。

しかし、PostgreSQL のシーケンスは MySQL より柔軟なので、次の戦略を推奨します。

GenerationType.SEQUENCEPostgreSQL はシーケンスに適しており、Hibernate

がシーケンスを自動で管理します。この場合、データベース側での追加のシーケンス作成が不要となり、効率的です。

例:

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "your_sequence")

@SequenceGenerator(name = "your_sequence", sequenceName = "your_sequence_name", allocationSize = 1)

 

まとめ

MySQL では、GenerationType.TABLE TABLE_PER_CLASS の組み合わせが適切です。

PostgreSQL では、GenerationType.SEQUENCE の使用をお勧めします。

 

 

8. Spring依存性注入とは

依存性注入 (DI : Dependency Injection)は、Springフレームワークの中心的な機能で、オブジェクト同士の依存関係を効率的に管理する方法です。オブジェクトが他のオブジェクトに依存する際、その依存関係を外部から「注入」することで、コードを柔軟にします。

 

8.1 DIの基本的な考え方

通常、オブジェクトが別のオブジェクトを必要とする場合、そのオブジェクトを自分で作成します。しかし、これでは依存関係が強くなり、コードの再利用やテストが難しくなります。DIを使うと、必要な依存オブジェクトを外部(コンテナ)から提供されるため、オブジェクト間の結びつきが緩やかになります。

 

8.2 DIの例

例えば、以下のようなクラスがあるとします。

public class Service {

    private Repository repository;

    public Service(Repository repository) {

        this.repository = repository;

    }

    public void performTask() {

        repository.save();

    }

}

ServiceクラスはRepositoryクラスに依存しています。通常はRepositoryのインスタンスをServiceクラス内で生成しますが、SpringではServiceのコンストラクタにRepositoryを渡すことで依存性を外部から注入します。

this.repository = new ConRepository();

とすると、Serviceクラスは、Repositoryインタフェースを実装した具象クラスConRepositoryと強く結びついてしまいます。

 

8.3 DIの仕組み

Springでは、DIを使ってオブジェクトの依存関係を設定できます。主な注入方法は3つあります。

·     コンストラクタインジェクション

コンストラクタを通じて依存オブジェクトを注入する方法です。上記の例がこれに該当します。

·     セッターインジェクション

セッターメソッドを使って依存オブジェクトを注入します。

public class Service {

    private Repository repository;

    public void setRepository(Repository repository) {

        this.repository = repository;

    }

}

·     フィールドインジェクション

フィールドに直接注入する方法で、@Autowiredアノテーションを使います。

public class Service {

    @Autowired

    private Repository repository;

}

 

8.4 DIのメリット

·     テストがしやすい: 依存関係を外部から注入するため、テスト時にモックオブジェクトを簡単に差し替えることができます。
·     コードの再利用性が高まる: 依存オブジェクトを外部から渡すことで、同じクラスを異なるシチュエーションで再利用できます。
·     結合度が低くなる: クラス間の依存関係を疎結合に保つことができ、コードが柔軟で変更に強くなります。

依存性注入は、より柔軟で保守性の高いアプリケーションを作るための非常に重要な概念です。Springフレームワークはこの仕組みを自動的に管理してくれます。

 

8.5 依存性とは

「依存性」とは、何かが他の何かに頼って動く関係のことです。例えば、車がガソリンに「依存」しているとしましょう。車はガソリンがないと動かないので、ガソリンに頼っている、つまり依存しているというわけです。

ソフトウェアでも、あるプログラム(車)が他のプログラム(ガソリン)を必要として動作する場合、その2つの間に「依存性」があるといいます。

 

8.6 注入とは

「注入」とは、必要なものを外から与えることです。車の例でいうと、車がガソリンスタンドで給油されるように、外からガソリンを「注入」されることです。つまり、車は自分でガソリンを作るのではなく、誰かがガソリンを入れてあげている状態です。

ソフトウェアの場合も同様で、必要なプログラム(例えば車でいうガソリン)を別のプログラムに「注入」して、うまく動くようにします。

 

依存性は、「あるものが他のものに頼っている関係」です。例えば、車がガソリンに頼って動いている状態。

注入は、「必要なものを外から与えること」です。車が自分でガソリンを用意するのではなく、外からガソリンを入れてもらうイメージです。

このように考えると、依存性と注入の関係は、何かを動かすために必要なものを外から提供してもらう仕組みだと言えます。

 

 

9. Springアノテーション

9.1 主要なアノテーション

(1) @Autowired

短い説明:Springによる依存性注入を行うアノテーション。

記述場所:フィールド、コンストラクタ、またはメソッド。

目的: Springが管理する任意のBean(オブジェクト)を注入するために使われます。

利用範囲: SpringDIコンテナで管理されている全てのオブジェクトに適用できます。例えば、サービスクラスやリポジトリクラスなどに依存するオブジェクトを注入する際に使います。

@Autowired

private MyService myService;

@Autowiredを使うことで、MyServiceクラスのインスタンスが自動的に注入され、myServiceというフィールドに格納されます。

補足: @Autowiredは、デフォルトでby type(型に基づいて)自動的に適切なBeanを見つけて注入します。必要に応じて@Qualifierを使い、特定のBeanを選択することも可能です。

(2) @Bean

短い説明:Springコンテナに管理されるBeanを定義するアノテーション。

記述場所:メソッド。

 

(3) @Component

短い説明:Springコンテナに管理される一般的なBeanを定義するアノテーション。

記述場所:クラス。

 

(4) @Configuration

短い説明:Springの設定クラスを示すアノテーション。

記述場所:クラス。

 

(5) @Controller

短い説明:Webリクエストを処理するコントローラを定義するアノテーション。

記述場所:クラス。

 

(6) @RestController

短い説明:REST APIのエンドポイントを定義するコントローラ用のアノテーション

@Controller + @ResponseBody)。

記述場所:クラス。

 

(7) @ResponseBody

短い説明:メソッドの戻り値をHTTPレスポンスのボディに直接変換するアノテーション。

記述場所:メソッド。

 

(8) @RequestMapping

短い説明:URLパスとリクエストハンドラをマッピングするアノテーション。

記述場所:クラスまたはメソッド。

 

(9) @GetMapping

短い説明:HTTP GETリクエストを処理するメソッドをマッピングするアノテーション。

記述場所:メソッド。

 

(10) @PostMapping

短い説明:HTTP POSTリクエストを処理するメソッドをマッピングするアノテーション。

記述場所:メソッド。

 

(11) @RequestParam

短い説明:HTTPリクエストのパラメータをメソッドの引数にバインドするアノテーション。

記述場所:メソッド引数。

 

(12) @ModelAttribute

短い説明:モデルデータをリクエストと共にバインドするアノテーション。

記述場所:メソッド、またはメソッド引数。

 

(13) @ControllerAdvice

短い説明:全体的な例外処理やモデルデータの共通処理を提供するアノテーション。

記述場所:クラス。

 

(14) @Repository

短い説明:データアクセス層(DAO)のBeanを定義するアノテーション。

記述場所:クラス。

 

(15) @Entity

短い説明:JPAエンティティクラスを示すアノテーション。

記述場所:クラス。

 

(16) @Table

短い説明:エンティティがマッピングされるデータベーステーブルを指定するアノテーション。

記述場所:クラス。

 

(17) @Id

短い説明:エンティティの主キーを指定するアノテーション。

記述場所:フィールドまたはメソッド。

 

(18) @Data

短い説明:Lombokによる自動的なゲッター、セッター、toString等の生成アノテーション。

記述場所:クラス。

 

(19) @Service

短い説明:ビジネスロジックを持つサービスクラスを定義するアノテーション。

記述場所:クラス。

 

(20) @Transactional

短い説明:メソッドやクラスに対してトランザクションの境界を定義するアノテーション。

記述場所:クラスまたはメソッド。

 

(21) @SpringBootApplication

短い説明:Spring Bootアプリケーションのエントリポイントを定義するアノテーション。

記述場所:クラス。

 

(22) @EnableScheduling

短い説明:スケジューリング機能を有効にするアノテーション。

記述場所:クラス。

 

(23) @ PersistenceContext

@Autowired@PersistenceContextはどちらも依存性注入を行うためのアノテーションですが、注入する対象や役割が異なります。

目的: 特定のEntityManagerを注入するために使われます。EntityManagerは、データベース操作を行う際に必要なJPAJava Persistence API)のインターフェースです。

利用範囲: 主にデータベースにアクセスするためのJPAJava Persistence API)関連クラスで使用されます。@PersistenceContextを使うことで、Springが管理するEntityManagerを注入し、データベースとのやり取りを実現します。

:

@PersistenceContext

private EntityManager entityManager;

@PersistenceContextを使うと、EntityManagerのインスタンスが自動的に注入され、entityManagerというフィールドで利用できるようになります。

補足: EntityManagerは、エンティティ(データベーステーブルの行に対応するオブジェクト)を操作するために使用されます。例えば、エンティティの保存、更新、削除、クエリ実行などを行うために重要です。

注入対象:

@PersistenceContextEntityManagerの注入に特化しています。

用途:

@PersistenceContextは、JPAを使ったデータベース操作でのみ使います。

補足:

@PersistenceContextの代わりに@Autowiredを使うと、次のような問題が発生する可能性があります。

·     トランザクションの管理

@PersistenceContextは、JPAEntityManagerを注入する際、トランザクションスコープで管理されるため、トランザクション開始や終了のタイミングに応じて自動的に正しいEntityManagerが提供されます。これにより、エンティティの状態が一貫性を保ち、トランザクションの境界内で適切に動作します。

一方、@AutowiredSpringの通常のBeanを注入するためのものです。もし@AutowiredEntityManagerを注入しようとすると、Springがトランザクションの境界を適切に管理できず、複数のトランザクション間で問題が発生する可能性があります。例えば、トランザクション内でEntityManagerが正しく解放されない、または使い回されるといった不具合が起きます。

·     スレッドセーフ性

@PersistenceContextを使うと、トランザクションスコープでEntityManagerが注入されるため、マルチスレッド環境でもスレッドごとに適切に分離されたEntityManagerが使用されます。

@Autowiredを使った場合、EntityManagerがシングルトンとして扱われる可能性があり、スレッド間で共有されるとスレッドセーフでなくなることがあります。これにより、同時実行中の複数のトランザクションで不整合が発生する可能性があります。

そのため、EntityManagerの注入には@PersistenceContextを使うべきで、@Autowiredではトランザクション管理やスレッドセーフ性の問題が起きる可能性があります。

 

(24) @Resource

目的: Javaの依存性注入を行うための標準アノテーションで、主に名前による依存性注入に使われます。

特徴: Spring@Autowiredが型に基づいて注入するのに対し、@Resourceは名前に基づいて依存性を解決します。

使用例:

@Resource(name="myBean")

private MyBean myBean;

 

(25) @Inject

目的: Javaの標準依存性注入アノテーション(JSR-330)。Spring@Autowiredに非常に似ていますが、標準のDIアノテーションです。

特徴: @Autowiredとほぼ同じ動作をしますが、Springに特化していないため、他のDIフレームワークでも使えることが特徴です。

使用例:

@Inject

private MyService myService;

 

(26) @EJB

目的: Java EEJakarta EE)の環境で使われるアノテーションで、**Enterprise Java BeansEJB**を注入するために使用します。

特徴: EJBを使用する際、@Autowiredではなく@EJBを使ってEJBコンポーネントを注入します。

使用例:

@EJB

private MyEJBService ejbService;

 

(27) @Value

目的: プロパティファイルなどから値を注入する際に使用します。

特徴: 値を直接コード内に埋め込むのではなく、設定ファイルから動的に読み込む際に使います。

使用例:

@Value("${app.name}")

private String appName;

 

(28) @ Transactional

目的: メソッドやクラスに対してトランザクション境界を定義するためのアノテーションです。

特徴: トランザクション管理を明示的に行う必要がある場合、@Transactionalを使用してトランザクションの開始・終了を自動的に管理します。

使用例:

@Transactional

public void saveData() {

    // データ保存処理

}

 

9.2 インスタンス化対象を指定

次のアノテーションを付けたクラスがインスタンス化の対象です。

@Component

@Controller

@Service

@Repository

@RestController

@ControllAdvice

ManagedBean

@Named

これらのアノテーションがついたクラスはコードのなかでnew()でインスタンス化することはなく、DIの仕組みによって呼び出し元クラスへ注入される

それが@Autowiredアノテーションを目印にして行われる。全般的な範囲の広いアノテーション

 

9.3 バリデーション関係

Bean Validationは対象クラスにチェックに応じたアノテーションを付与して使用します。

以下は入力値やロジックによるチェック時によく使用されるバリデーション用アノテーションです。

@Validated

@AssertTrue

@AssertFalse

@Null

@NotNull

@NotBlank

@Max(value)

@Min(value)

@DecimalMax(value, inclusive)

@DecimalMin(value, inclusive)

@Positive

@PositiveOrZero

@Negative

@NegativeOrZero

@Digits(integer, fraction)

@DateTimeFormat(Date format)

@Size(max or min=value)

@Email

@Pattern(regex, flags)

 

 

10. コントローラとビューの間のデータの受け渡し

10.1 View Controller

·     @RequestParam

このアノテーションは、リクエストパラメータを引数として受け取る際に使用します。

主にフォームの入力やURLクエリパラメータを取得するのに使われます。

例えば、/greet?name=John のようなリクエストで「name」というパラメータを受け取る場合、@RequestParam を使います。

 

@GetMapping("/greet")

public String greet(@RequestParam("name") String name, Model model) {

    model.addAttribute("name", name);

    return "greet";

}

 

·     @ModelAttribute

このアノテーションは、フォームデータやリクエストボディのデータをオブジェクトにバインドするために使用します。主にフォームのデータを複数のフィールドにまとめて受け取る場合に使われます。例えば、ユーザーオブジェクト全体をフォームから取得する場合に便利です。

 

@PostMapping("/register")

public String register(@ModelAttribute User user, Model model) {

    model.addAttribute("user", user);

    return "register";

}

@RequestParamは個別のパラメータを、@ModelAttributeはオブジェクト全体を受け取るといった役割で使用されます。

 

他の方法

·     @RequestBody

このアノテーションは、リクエストボディ全体を直接Javaオブジェクトに変換して受け取るのに使用します。

特に、JSON形式のデータを受け取る際に役立ちます。REST APIでよく使います。

@PostMapping("/api/data")

public ResponseEntity<String> postData(@RequestBody Data data) {

    // JSONをオブジェクトにバインド

    return ResponseEntity.ok("Success");

}

 

·     PathVariable

パスの一部を引数として受け取る際に使います。

@GetMapping("/user/{id}")

public String getUser(@PathVariable("id") Long id, Model model) {

    model.addAttribute("userId", id);

    return "user";

}

 

10.1.1 補足説明

Spring Bootでは、フォームクラスに対応しない入力フィールドの値を受け取るためにさまざまな方法を提供しています。

たとえば、@RequestParamアノテーションを使用して直接リクエストパラメータを取得できます。

また、@ModelAttributeアノテーションを使用してフォームクラス以外のオブジェクトにデータをバインドできます。

要するに、Spring Bootではフォームクラスを使用してフォームデータを受け取ることが一般的ですが、他の方法を使ってフォームクラスに定義されていない入力フィールドの値を受け取ることも可能です。

 

10.2 Controller View

·     Model

ControllerからViewにデータを渡す際に、Modelを使ってデータを追加します。

これは最も一般的な方法です。

 

@GetMapping("/show")

public String show(Model model) {

    model.addAttribute("message", "Hello World");

    return "show";

}

·     ModelAndView

ModelAndViewは、モデルとビューを同時に返すことができるクラスです。

ビュー名とモデルを一緒に扱う場合に便利です。

 

@GetMapping("/show")

public ModelAndView show() {

    ModelAndView mav = new ModelAndView("show");

    mav.addObject("message", "Hello World");

    return mav;

}

 

·     RedirectAttributes

リダイレクト時に一時的にデータを渡すために使用します。

RedirectAttributesは一度だけ使用される一時的なデータを渡すために便利です。

 

@PostMapping("/submit")

public String submit(RedirectAttributes redirectAttributes) {

    redirectAttributes.addFlashAttribute("message", "Data submitted successfully");

    return "redirect:/result";

}

これらの方法を組み合わせて、用途に応じたデータの受け渡しが可能です。

 

11. Springアスペクト指向プログラミング

Spring AOP (Aspect-Oriented Programming) は、横断的な関心事(cross-cutting concerns)をモジュール化するためのプログラミング手法です。横断的な関心事とは、アプリケーション全体にまたがる共通の機能のことを指し、ログ出力やトランザクション管理、セキュリティなどが典型例です。

AOP の基本的な考え方は、これらの横断的な機能をアプリケーションの本来のビジネスロジックとは分離し、個別に管理できるようにすることです。これにより、コードの重複を減らし、保守性や可読性を向上させます。

 

11.1 構成要素

Spring AOP では、以下の5つの要素が基本的な構成要素です:

11.1.1 アスペクト(Aspect

横断的な機能そのものです。たとえば、ログ出力や例外処理をひとつのアスペクトとして実装します。

 

11.1.2 アドバイス(Advice

アスペクトがいつ実行されるかを定義します。メソッドの実行前、実行後、例外発生時など、どのタイミングで横断的な処理を行うかを指定します。

 

11.1.3 ジョインポイント(Join Point

アスペクトが適用される具体的なポイントです。Spring では、主にメソッド呼び出しがジョインポイントとなります。

 

11.1.4 ポイントカット(Pointcut

ジョインポイントをフィルタリングし、どのメソッドにアドバイスを適用するかを定義します。正規表現やアノテーションを使って、対象となるメソッドを柔軟に指定できます。

 

11.1.5 ターゲット(Target

アスペクトを適用されるオブジェクト、つまりビジネスロジックを持つクラスです。

 

11.2 簡単な例

たとえば、特定のメソッドが実行される前にログを出力するアスペクトを作成する場合、以下の流れとなります:

(1) @Before アノテーションを使って、メソッドの実行前にログ出力を行うアドバイスを定義。

(2) ポイントカットで、どのメソッドに対してこのアドバイスを適用するかを指定。

 

@Aspect

@Component

public class LoggingAspect {

    @Before("execution(* com.example.service.*.*(..))")

    public void logBefore(JoinPoint joinPoint) {

        System.out.println("Executing method: " + joinPoint.getSignature());

    }

}

 

このコードでは、com.example.service パッケージ内のすべてのメソッドが実行される前に、メソッド名をログに出力します。

Spring AOP を使用すると、ビジネスロジックに直接関与しないコードを分離し、関心ごとに応じた処理を柔軟に追加できるようになります。

 


 

12. Spring JPA 永続化

12.1 エンティティオブジェクトの状態遷移

 

12.2 エンティティオブジェクトの状態

状態名

概要

NEW状態

エンティティオブジェクトを生成(new)しただけでの状態です。永続化コンテキストとは関連付けられていません。

MANAGED状態

エンティティオブジェクトは永続化コンテキストと関連付けられた状態です。EntityManager#findで検索可能です。

DETACHED状態

エンティティオブジェクトは永続化コンテキストと関連付けられていません。

MANAGED状態からDETACHED状態への遷移は

EntityManager#clear または EntityManager#close で操作できます。

もう一つ、トランザクションに関係した挙動でも遷移します(後述:merge 参照)

REMOVED状態

削除された状態です。EntityManager#persist で再びMANAGED状態に遷移できます。

 

12.3 トランザクション境界での状態遷移の挙動

 

 
·     merge メソッドのAPI doc

<T> T merge(T entity)

Merge the state of the given entity into the current persistence context.

Parameters:

entity - entity instance

Returns:

the managed instance that the state was merged to

Throws:

IllegalArgumentException - if instance is not an entity or is a removed entity

TransactionRequiredException - if there is no transaction when invoked on a container-managed entity manager of that is of type PersistenceContextType.TRANSACTION

 

13. MySQL

MySQL80 MySQLWorkbench8.0 を前提に説明します。

MySQLでは「データベース」と「スキーマ」を区別しません。本書では同意語として使います。

 

13.1 データベースの作成

(作成例)

(1)  [create a new schema]というボタンをクリック(赤枠内をクリック)

(2) Nameには、登録したいスキーマの名前を入力

(3) charset(文字セット)/collation(デフォルトの照合順序)には、utf8/utf8_general_ci を選択

(4) Applyで確定

 

 

13.2 ユーザとパスワードの作成

(作成例)

 

13.2.1 usernamepassword の確認方法と設定方法

(1) MySQL Workbenchでユーザー情報を確認する方法:

MySQL Workbench を開き、MySQL インスタンスに接続します。

メインメニューから「Server(サーバー)」 -> User and Privileges(ユーザーと権限)」をクリックします。

左側のユーザーリストから確認したいユーザー名(例: mainbank)を選択します。

右側に選択したユーザーの詳細(認証方式、パスワード、権限など)が表示されます。

(2) ユーザー名とパスワードの設定方法:

上記の「User and Privileges」画面で、パスワードを変更したい場合は、「Login(ログイン)」タブで password フィールドを変更し、適用します。

新しいユーザーを追加したい場合は、同じ画面の「Add Account(アカウントを追加)」ボタンを押し、新しいユーザー名とパスワードを設定し、適切な権限を割り当てます。

 

13.3 application.propertiesの設定

(設定例)

spring.application.name=mainbank

spring.thymeleaf.mode=HTML

spring.datasource.url=jdbc:mysql://localhost:3306/db_mainbank?serverTimezone=UTC

spring.datasource.username=mainbank

spring.datasource.password=mainbank

# spring.datasource.driver-class-name =com.mysql.jdbc.Driver =>  'com.mysql.jdbc.Driver'. This is deprecated.

spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver

spring.jpa.database=MYSQL

# create-drop cause Error executing DDL "alter table

#none / validate / update / create / create-drop / drop

spring.jpa.hibernate.ddl-auto=update

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

spring.jpa.show-sql: true

spring.security.user.name=test

spring.security.user.password=test

#platform line seems unnecessary

#spring.datasource.platform=mysql

 

13.4 データベースとスキーマ

MySQLの場合、データベースとスキーマはほぼ同じ意味で使われます。

·     データベース: MySQLでは「データベース」は、テーブルやビューなどのデータオブジェクトが保存される領域のことを指します。
·     スキーマ: 一部のデータベースシステムでは、スキーマはデータベース内でテーブルや他のオブジェクトの構造を定義する「論理的なコレクション」です。

 

13.5 spring.jpa.hibernate.ddl-autoの設定

Spring Boot アプリケーションにおける Hibernate のデータベーススキーマの自動生成や変更に関する設定です。これには複数のオプションがあり、それぞれ異なる挙動を持っています。

 

13.5.1 代表的なオプション

(1) none

 挙動: Hibernate がスキーマ管理を一切行わず、データベースの構造はそのままです。

 用途: スキーマの自動生成や変更を避けたい場合。既存のスキーマがあり、手動で管理したいときに使用します。

(2) validate

 挙動: エンティティの定義とデータベースのスキーマが一致しているかを検証しますが、データベースに対して何も変更を加えません。

 用途: スキーマが正しく設定されているか確認したい場合や、変更を加えずにスキーマの整合性をチェックしたい場合に適しています。

(3) update

 挙動: エンティティの定義に基づいて、必要なテーブルやカラムを作成・更新します。ただし、既存のデータや構造を削除することはありません。

 用途: スキーマを自動的に変更したい場合や、既存のデータを維持したまま、変更を反映したい場合に適しています(現状これを使用中ですね)。

(4) create

 挙動: アプリケーション起動時に既存のスキーマをすべて削除し、新しくスキーマを作成します。アプリケーション終了時にはスキーマは削除されません。

 用途: 開発環境で新しいスキーマをすぐに作りたい場合に使用されますが、既存データは消えるため注意が必要です。

(5) create-drop

 挙動: アプリケーションの起動時にスキーマを作成し、終了時にスキーマを削除します。

 用途: テストや一時的な環境で、スキーマを簡単に作成し、使用後にクリーンアップしたい場合に使用します。

(6) drop

 挙動: アプリケーション起動時にスキーマを削除し、その後何もしません。

 用途: 一般的にはあまり使用されませんが、起動時に明示的にスキーマを削除したい場合に使用します。

 

13.5.2 オプションのまとめ

 none: スキーマ操作をしない(手動管理)。

 validate: スキーマの検証のみ(変更なし)。

 update: スキーマの更新(データは保持)。

 create: スキーマを再作成(データは削除)。

 create-drop: 起動時にスキーマを作成し、終了時に削除。

 drop: スキーマを削除。

update は開発時に便利ですが、本番環境では validate none を使って、スキーマを手動で管理するのが一般的です。

 

14. Tipsレンダリング

レンダリングとは、Webアプリ開発の文脈では、クライアントサイド・レンダリングやサーバサイド・レンダリングのようにHTMLデータを生成する処理を指します。

また、最終的に、ブラウザがデータ(HTMLなど)を視覚化する処理を指す場合もあります。

 

14.1 サーバサイドレンダリング(Server-Side Rendering, SSR

JSPJavaServer Pages)はサーバーサイドレンダリングの一種です。

サーバーサイドレンダリングとは、サーバー側でHTMLを生成してクライアント(ブラウザ)に送信する方法です。

JSPJavaでサーバーサイドのコードを実行し、その結果をHTMLとして生成します。具体的には、JSPページはJavaコードやJSPタグを含んでおり、サーバー上で実行されると、その出力がHTMLとして生成され、クライアントに送信されます。

JSPのレンダリングプロセスは次のようになります:

(1) クライアントがJSPページにリクエストを送信する。

(2) サーバーがJSPファイルを受け取り、Java Servletとしてコンパイルする。

(3) コンパイルされたServletが実行され、HTML出力を生成する。

(4) 生成されたHTMLがクライアントに送信され、ブラウザで表示される。

このように、JSPはサーバーサイドで実行されるため、サーバーサイドレンダリングの一部とされています。

 

14.2 クライアントサイドレンダリング(Client-Side Rendering, CSR

(1) JavaScriptフレームワーク

React, Angular,Vue.js などのJavaScriptフレームワークはクライアントサイドレンダリングを前提として設計されています。これらのフレームワークは、コンポーネントベースのアーキテクチャを使用して、クライアント側で効率的にUIを構築・更新します。

(2) SPASingle Page Application

クライアントサイドレンダリングは、一般的にSPAアプリケーションで使用されます。SPAでは、最初に必要なHTMLCSSJavaScriptをロードし、その後のページ遷移はJavaScriptによって行われ、サーバーから新しいHTMLを取得するのではなく、必要なデータだけをフェッチして、ページを動的に更新します。

 

14.3 静的サイト生成(Static Site Generation, SSG

ウェブサイトのページを事前に生成し、それらを静的ファイル(通常はHTMLCSSJavaScriptなど)としてサーバーに配置する手法です。SSGは、あらかじめ定義されたテンプレートとデータを基に、ビルド時に全てのページを生成するので、リクエスト時にサーバー側で動的に生成する必要がなく、非常に高速で効率的です。

 

15. Tips:セレクトボックスの書き方

·     HTML素のコード

<select name="example">

<option value="サンプル1">サンプル1</option>

<option value="サンプル2">サンプル2</option>

<option value="サンプル3">サンプル3</option>

</select>

 

·     JSP JSTLを使うとき

<c:forEach items="${itemAry}" var="item" varStatus="status">

 <option value="${status.count}" <c:if test="${status.count==itemIndexStr}">selected</c:if>> ${item}</option>

</c:forEach>

 

·     Spring (Spring MVC) を利用したとき

<!--職種 -->

<div class="mr-2">

<form:select path="jobTypeId" onchange="showHome()">

<form:options items="${jobTypeList}" itemLabel="label" itemValue="id" /

</form:select>

</div>

 

·     Thymeleafを利用したとき

<select class="dropdown form-control">

    <option th:value="0"></option>

    <option th:each="item : ${mDepartmentMap}" th:value="${item.value}" th:text="${item.key}"></option>

</select>