6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Spring BootのWebアプリケーションの基本② 〜MVCモデルとEntityとlombok~

Last updated at Posted at 2023-08-06

前回の記事では、IntelliJの簡単な使い方やMVCモデルについて説明をしてきました。

今回からは実際にWebアプリケーションの開発をしていきます。

今回のファイル構成は、以下になります。

ファイル構成(クリックして展開)


.
├── .gradle
├── .idea
├── build
├── gradle
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── practice 
    │   │               └── PracticeApplication.java
    │   │               ├── web 
    │   │               │   ├── order
    │   │               │   │   └── OrderController.java
    │   │               │   └── indexController.java
    │   │               └── domain
    │   │                   └── order 
    │   │                       └── OrderEntity.java
    │   └── resources
    │       ├── static
    │       ├── templates
    │       │   ├── order
    │       │   └── list.html
    │       └── index.html
    │       └── application.properties
    └── test
.gitignore
build.gradle
gradlew.bat
HELP.md
settings.gradle

では、今回はMVCモデルに従って、Webアプリケーションを作成していきたいと思います。

Modelの作成(Entity)

最初に作成するのは、Entityです。 Entityはデータベースのテーブル構造を表したオブジェクトを言います。

Entityデータベース内の特定のテーブルに関するデータや振る舞いをオブジェクト指向のアプローチで捉え、プログラム内で扱いやすい形にすることを目的としています。

一方で、「Model」は、アプリケーション内のビジネスロジックやデータ処理を担当する部分を指します。MVCモデルでは、「Model」がデータの管理とビジネスロジックの実装を担当し、データベースの「Entity」もその一部として含まれます。

オブジェクトの説明をする前にクラスの説明をしたいと思います。

今回は、以下のようにOrderEntityのクラスを作成しますが、以下の状態では、実際の機能として動かすには、まだ実体を持っていないため、動かすことはできません。

クラスは、あくまで、実体を作るための設計図です。
クラスの中には、実体を持つであろうものの属性(フィールド)や機能(メソッド)が書かれています。
クラスでは、様々なフィールドやメソッドを持っており、それらをひとまとめにして、ひとつの型として捉えたものがオブジェクトです。

今回の例で言えば、下のコードのように記述する。

OrderEntity
package com.example.practice.domain.practice;

public class OrderEntity {
     //ここにフィールドやメソッドなどを記述する
}

フィールド

フィールドは、クラスの中でデータの値を保管するためものです。
フィールドを定義する場合は、次のように行います。

class  クラス名 {
  データ型 フィールド名;
}

今回のOrderEntity.javaでは、以下のように記載します。

OrderEntityはドメインに属するクラスなので、domainの配下に作成します。

ちなみに、ドメイン層は、 アプリケーション層に提供する業務ロジックを実装するための階層です。

ドメイン層は、主に、データを保持するためのクラスであるEntityの実装とデータを操作するためのメソッドであるRepositoryの実装、業務ロジックを実行し、アプリケーション層に提供するServiceの実装の3つに分かれます。

src/main/java/com/example/practice/domain/OrderEntity.java

package com.example.practice.domain.order;

public class OrderEntity {
    /*
    フィールド(メンバ変数)
    */
    //注文番号
    private int orderId;
    //日付
    private String orderDate;
    //会社番号
    private int companyNo;
    //会社名
    private String companyName;
    //品物番号
    private int ItemNo;
    //品物
    private String Item;
    //数量
    private int quantity;
    //単価
    private int unitPrice;
    //金額
    private int price;
}

メソッド

次は、メソッドは、内容がまとまっている処理や反復する処理など、プログラムの処理を一つにまとめたものです。

次は、コンストラクタを設定していきます。

コンストラクタとは、クラスからオブジェクトを作成した際に、自動的に実行されるメソッドで、クラス名と同名のメソッド名にする必要があります。

以下は、自動的に実行されるメソッドで、orderIdの引数で渡された値をthis.orderIdに渡すようにしています。

src/main/java/com/example/practice/domain/OrderEntity.java
package com.example.practice.domain.order;
public class OrderEntity {
    /*
    フィールド(メンバ変数)
    */
    //注文番号
    private int orderId;
    /*
    同じコードのため、省略
    */
    //金額
    private int price;
    /*
    コンストラクタを定義する
    */
    public orderEntity(
            int orderId,
            String orderDate,
            int companyNo,
            String companyName,
            int itemNo,
            String item,
            int quantity,
            int unitPrice,
            int price
    ) {
        this.orderId = orderId;
        this.orderDate = orderDate;
        this.companyNo = companyNo;
        this.companyName = companyName;
        this.item = item;
        this.itemNo = itemNo;
        this.quantity = quantity;
        this.unitPrice = unitPrice;
        this.price = price;
    }
}

getterとsetterとは

次に、getterとsetterを設定する。

getterとは、setterでセットしたフィールドの値を取得して、returnで呼び出した元に値を返すメソッドのこと。

getterの基本的な書き方は以下の通りです。

private String getSample() {
    return sample;
}

setterは呼び出し元のメソッドから値を引数で受け取り、引数の値をthisを使ってフィールドにセットしている。

public void setSample(String sample) {
    this.sample = sample;
  }

以下がgetterとsetterの処理を追加したorderEntity.javaのコードになる。

src/main/java/com/example/practice/domain/OrderEntity.java
package com.example.practice.domain.order;

public class OrderEntity {
    /*
    フィールド(メンバ変数)
    */
    //注文番号
    private int orderId;
    //日付
    private String orderDate;
    //会社番号
    private int companyNo;
    //会社名
    private String companyName;
    //品物番号
    private int itemNo;
    //品物
    private String item;
    //数量
    private int quantity;
    //単価
    private int unitPrice;
    //金額
    private int price;
    /*
    コンストラクタを定義する
    */
    public OrderEntity(
            int orderId,
            String orderDate,
            int companyNo,
            String companyName,
            int itemNo,
            String item,
            int quantity,
            int unitPrice,
            int price
    ) {
        this.orderId = orderId;
        this.orderDate = orderDate;
        this.companyNo = companyNo;
        this.companyName = companyName;
        this.item = item;
        this.itemNo = itemNo;
        this.quantity = quantity;
        this.unitPrice = unitPrice;
        this.price = price;
    }
    /*
    getterとsetterを定義する
    */
    public int getOrderId() {
        return orderId;
    }

    public void setOrderId(int orderId) {
        this.orderId = orderId;
    }
    public String getOrderDate() {
        return orderDate;
    }

    public void setOrderId(String orderDate) {
        this.orderDate = orderDate;
    }
    public int getCompanyNo() {
        return companyNo;
    }

    public void setCompanyNo(int companyNo) {
        this.companyNo = companyNo;
    }
    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }
    public String getItem() {
        return item;
    }

    public void setItem(String item) {
        this.item = item;
    }
    public int getItemNo() {
        return itemNo;
    }

    public void setItem(int itemNo) {
        this.itemNo = itemNo;
    }
    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }
    public int getUnitPrice() {
        return unitPrice;
    }

    public void setUnitPrice(int unitPrice) {
        this.unitPrice = unitPrice;
    }
    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}
}

Viewの作成

Viewは、ウェブアプリケーションの外部からの入力や表示を行う部分です。 ここでは、Thymeleafというテンプレートエンジンを使用して、HTML内に動的なデータを埋め込むやり方で、list.htmlを作成します。
src/resources/templates/order/list.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>注文リスト</title>
</head>
<body>
<h1>注文リスト</h1>
<table>
    <tr>
        <th>注文番号</th>
        <th>日付</th>
        <th>会社番号</th>
        <th>会社名</th>
        <th>品物番号</th>
        <th>品物</th>
        <th>数量</th>
        <th>単価</th>
        <th>金額</th>
    </tr>
    <!-- orderList の内容をループして表示 -->
    <tr th:each="order : ${orderList}">
        <td th:text="${order.orderId}"></td>
        <td th:text="${order.orderDate}"></td>
        <td th:text="${order.companyNo}"></td>
        <td th:text="${order.companyName}"></td>
        <td th:text="${order.itemNo}"></td>
        <td th:text="${order.item}"></td>
        <td th:text="${order.quantity}"></td>
        <td th:text="${order.unitPrice}"></td>
        <td th:text="${order.price}"></td>
    </tr>
</table>
</body>
</html>

th:text="${order.orderId}" の部分は、order という名前のオブジェクトから orderId フィールドの値を取り出し、その値をセル内に表示するためのコードです。同様に、他のフィールドも動的に埋め込まれます。

こうしたテンプレートの利用により、サーバー側で取得したデータを動的にHTMLに組み込むことができ、ユーザーに最終的な表示を提供することができます。

Controllerの作成

次に、OrderControllerを作っていきます。
ControllerはModelとViewのそれぞれの処理をアプリとして連携させるために、司令塔や橋渡し役という役割を担います。
ユーザーのリクエストを受け取り、適切なモデルを操作して結果をビューに渡します。

今回は、あらかじめ、モデルにデータをセットし、データがビューで表示されるようにしていきたいと思います。

以下のコードがモデルにデータをセットし、データがビューで表示されるコードです。

src/main/java/com/example/practice/web/order/OrderController.java

package com.example.practice.web.order;

import com.example.practice.domain.order.OrderEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.List;

@Controller
public class OrderController {

    // GETリクエストを受け取り、オーダーリストを作成し、ビューに渡すメソッド
    @GetMapping("/orders")
    public String showList(Model model) {
        // OrderEntityクラスのオブジェクトを作成し、リストに追加
        var orderList = List.of(
                new OrderEntity(1000, "20230801", 1000,
                        "株式会社あいうえお", 1000, "パソコン", 1, 100000,
                        100000),
                new OrderEntity(1001, "20230802", 1001,
                        "株式会社ABCD", 1001, "デスクトップ", 2, 60000,
                        120000)
        );

        // OrderListをThymeleafのビューで利用できるようにモデルに追加
        model.addAttribute("orderList", orderList);

        // "order/list"という名前のThymeleafビューを表示する
        return "order/list";
    }
}

Spring Bootアプリケーションのコントローラクラスで、GETリクエストが /orders エンドポイントに送信されると、showListメソッドが実行されます。

このメソッドでは、orderEntityクラスのオブジェクトを作成して、それをリストに追加します。そして、作成したリストをThymeleafのビューで利用できるようにmodel.addAttribute("orderList", orderList);を使ってモデルに追加します。最後にreturn "order/list"; によって、Thymeleafのテンプレートエンジンにより、名前が "orders/list" のビューが表示されます。このビューには、orderListの内容を動的に表示することができます。

その後に、「http://localhost:8080/orders」このURLをクリックすると、OrderControllerで登録した値が表示されます。

スクリーンショット 2023-08-07 7.55.54.png

lombok

ここでは、コンストラクターやgetterとsetterのコードを自動生成するLombokを紹介します。

build.gradleに以下を追加します。

build.gradle
configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}
configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}
dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

その次に、「IntelliJ IDEA」→Setting→pluginを押し、「Lombok」を追加する。

スクリーンショット 2023-08-16 11.06.28.png

OrderEntityは簡略化されるので、活用してみてくださいね。

src/main/java/com/example/practice/domain/OrderEntity.java
package com.example.practice.domain.order;

import lombok.AllArgsConstructor;
import lombok.Data;

@AllArgsConstructor
@Data
public class OrderEntity {
    /*
    フィールド(メンバ変数)
    */
    //注文番号
    private int orderId;
    //日付
    private String orderDate;
    //会社番号
    private int companyNo;
    //会社名
    private String companyName;
    //品物番号
    private int itemNo;
    //品物
    private String item;
    //数量
    private int quantity;
    //単価
    private int unitPrice;
    //金額
    private int price;
}

まとめ

この記事では、MVCモデルに従ったWebアプリケーションの開発手順を詳しく説明しました。最初にModelの作成を行い、Entityクラスを定義し、データベースのテーブル構造をオブジェクト指向で表現しました。クラス内には、属性やコンストラクタ、getterとsetterを記述し、オブジェクトの設計図としての役割を説明しました。

その後、Viewの作成を行い、Thymeleafテンプレートエンジンを用いてHTML内に動的なデータを埋め込む方法を示しました。コード例を通じて、orderListの内容をループして表示する方法や、データの動的な表示を実現する手法について説明しました。

また、Controllerの作成についても解説しました。ControllerはModelとViewを連携させる役割を果たし、ユーザーのリクエストを受け取り、適切なモデルを操作して結果をビューに渡すプロセスを説明しました。具体的には、GETリクエストを受け取り、orderEntityオブジェクトを作成し、それをリストに追加してビューに渡す手順を示しました。

さらに、Lombokという便利なライブラリを紹介し、コードを簡略化する方法を提案しました。Lombokを使用することで、コンストラクタやgetterとsetterのコードを自動生成し、効率的なプログラミングを実現できることを説明しました。

この記事を通じて、MVCモデルを活用したWebアプリケーションの開発手法や、Entityの設計、Thymeleafの利用方法、Controllerの役割、さらにはLombokの活用法について理解を深めることができたと思います。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?