😸

SpringBootでアプリ作ってみる1️⃣(DBリクエストでDBの値を取得まで)

2024/09/09に公開

目次

1 Pleades(STS)をDL

公式サイトよりDL

2 プロジェクト作成

新しいプロジェクトの作成メニューから File > New > Spring Starter Project を選択


確認

pom.xml

ライブラリの説明
ライブラリ名 必須 (個人的) 説明
spring-boot-starter Springを導入する際には必須
Spring Web WEBアプリケーションを開発するために必要な機能を提供する。
Spring Boot DevTools ホットリロードを提供 (アプリケーション起動中にコードを編集した場合に自動的に反映する)
Spring Security ログイン機能やサインイン機能などを実装するためには必須
Validation WEBアプリケージョンでよく使われるバリデーションを実装するために必要
thymeleaf テンプレートエンジン。必須
Spring Boot starter test テスト機能を実装する際に必要。
Lombok Getter/Setterなど機械的に作成するメソッドをアノテーションのみで自動生成するライブラリ。

3 DockerでMySQLを起動

  • 「--name mysql-container」コンテナの名前
  • 「-e MYSQL_ROOT_PASSWORD=my-secret-pw」ルートユーザのパスワード
  • 「-p 3306:3306」ホストのポート3306にアクセスすると、コンテナのポート3306にアクセス
  • 「-v /my/own/datadir:/var/lib/mysql」ホストマシンのディレクトリ /my/own/datadir をコンテナ内の /var/lib/mysql にマウント
  • 「-d」コンテナをデタッチドモード(バックグラウンド)で実行
  • 「mysql:latest」最新のDockerイメージを指定
docker run --name mysql-container -e MYSQL_ROOT_PASSWORD=my-secret-pw -p 3306:3306 -v /my/own/datadir:/var/lib/mysql -d mysql:latest
vオプションの利用目的
  1. データ永続化
    1. バインドマウント
    2. ボリューム
      「ホストのディレクトリ」や「新たに作成したボリューム」をマウントすることでデータを永続化させる
      1. ホストのディレクトリ
        「-v ホストマシンのディレクトリ:Dockerコンテナのディレクトリ」
        ディレクトリを共有するので見やすいが、権限の関係で起動しないこともあるみたい
        https://qiita.com/ysd_marrrr/items/e8a50c43cff87951385c
        例)Windowsの場合「-v c/dev:/var/lib/mysql」
      2. 新たに作成したボリューム
        推奨。Dockerのコマンドでボリュームを作成→それをマウントの流れ
        https://zenn.dev/satonopan/articles/43ba26f97a8388
        「-v vol1:/tmp/volume」
  2. データの共有
    1. 複数のコンテナで同じホスト先のフォルダをマウントすれば、複数コンテナ内でのデータの共有ができる
  3. 設定ファイルの受け渡し
    1. 設定ファイルをマウントしておくと、その設定を変えるだけでコンテナの設定を変更できる
用語
  1. マウント
    「対象」を接続して、OS・アプリが操作できるようにすること。
    例)パソコンにマウスを接続して、OSがマウスを操作できるようにする。
  2. ボリューム
    外部記憶装置のこと
    例)PCにUSBを接続したとき、ドライブを接続したときにボリューム:Cとか出るやつがそれ
課題
  • ymlで管理する
  • マウントはディレクトリではなくボリュームにしてみる(ボリュームの中身見る方法も)
  • パスワード直に記載はまずいので環境変数はでどうにかする方法
  • ymlで管理する
ホスト先のディレクトリにMySQLのデータが作成されていることを確認

4 DB定義

  • クライアントはHeidi SQL
  • 「is_complete TINYINT」・・・booleanないので、TINYINT(booleanで作成してもどちらにせよTINYINTで作成される)
  • 「CHECK (is_complete >= 0 AND is_complete <= 1)」・・・0と1以外入れないように
create database tododb;
CREATE TABLE tasks (
    id int AUTO_INCREMENT PRIMARY KEY,
    task_name varchar(100) NOT NULL,
    scheduled_completion_on DATETIME NOT NULL,
    is_complete TINYINT NOT NULL,
    created_at DATETIME NOT NULL,
    updated_at DATETIME NOT NULL,
    CHECK (is_complete >= 0 AND is_complete <= 1)
);

5 DB設定(アプリ)

applicationj.properties
# データベースの接続URL
# データベースへの接続URLを指定します。ホスト名、ポート番号、データベース名を含みます。
spring.datasource.url=jdbc:mysql://localhost:3306/tododb

# データベースのユーザー名
# データベースのユーザー名
spring.datasource.username=root

# データベースのパスワード
spring.datasource.password=my-secret-pw

# JDBCドライバのクラス名
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# JPA(Hibernate)の設定
# Hibernateによるスキーマ自動更新の設定です。update、create、create-drop、validate、noneなどのオプションがあります。
spring.jpa.hibernate.ddl-auto=update

# HibernateのSQL方言
# 使用するデータベースの方言を指定します。
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

# ログの設定(SQLクエリをログに出力)
# このプロパティをtrueに設定すると、実行されたSQLクエリがログに出力されます。
spring.jpa.show-sql=true

課題
  • ソースにパスワード記載したらだめでしょ

6 エンティティ作成

  • テーブルにマッピングされるイメージ(ここではtasksテーブル)
  • lombokライブラリの@Dataアノテーションでゲッター、セッター、equals()とhashCode()、コンストラクタが生成される
  • @EntityアノテーションでEntityであることを宣言
  • @Tableアノテーションでテーブルと紐づけ
  • @IdアノテーションでID列であることを宣言
  • @GeneratedValueで採番方法を選択(MySQLなのでIDENTITY)
  • @Columnアノテーションでフィールドとカラムを紐づけ
  • @Temporalアノテーションで日付型の場合になんとかする
Tasks.java
@Data
@Entity
@Table(name = "tasks")
public class Tasks {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "task_name")
private String taskName;

@Column(name = "scheduled_completion_on")
private LocalDateTime scheduledCompletionOn;

@Column(name = "is_complete")
private int isComplete;

@Column(name = "created_at")
private LocalDateTime createdAt;

@Column(name = " updated_at")
private LocalDateTime updatedAt;

DBでDATETIME型をJavaでマッピングさせるときのJavaの型
クラス名 推奨 備考
java.util.Date 非推奨
java.time.LocalDateTime 日付時刻を操作・保持する。
java.time.LocalDate 日付を操作・保持する。時刻データは保持していない。
java.time.LocalTime 時刻を操作・保持する。日付データは保持していない。

7 エンティティ作成

  • DAOみたいなもの
  • DBやAPIとやり取りするクラス(インターフェースみたいな)
  • JpaReositoryインターフェースを継承しているので下記のメソッドを利用可能
    • save(S entity): エンティティを保存または更新します。
    • findById(ID id): IDに基づいてエンティティを取得します。
    • findAll(): 全てのエンティティを取得します。
    • deleteById(ID id): IDに基づいてエンティティを削除します。
  • JpaReository<テーブル名、ID>で紐づけ
@Repository
public interface TasksRepository extends JpaRepository<Tasks, Long> {
}

8 サービス作成

  • 処理書くところ
  • @Serviceでサービスであることを明記
  • クラス名は~Service
  • @AutowierdアノテーションでTaskRepositoryと紐づけしている。実際はインスタンス化?
@Service
public class TasksService {
@Autowired
private TasksRepository tasksRepository;

public List<Tasks> getAllUsers() {
return tasksRepository.findAll();
}

public Tasks getTasksById(Long id) {
return tasksRepository.findById(id)
.orElse(null);
}
}

9 コントローラ作成

  • リクエストを受け取る
  • レスポンスを返す。
@RestController
@RequestMapping("/tasks")
public class TaskController {
  @Autowired
  private TasksService tasksService;

  @GetMapping
  public List<Tasks> getAllTasks() {
    return tasksService.getAllTasks();
  }

  @GetMapping("/{id}")
  public Tasks getTaskById(@PathVariable Long id) {
    return tasksService.getTasksById(id);
  }
}

10 エントリークラスを作成

  • 「@SpringBootApplication」アノテーションが付与されたクラスのパッケージ、サブパッケージ内のコントローラーがアプリケーション開始時にスキャンされる。
  • 「@ComponentScan」アノテーションを付与することで、スキャンパッケージを指定することができる
  • 「SpringApplication.run」はSpringBootの開始メソッド。
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan(basePackages = {"com.example.demo", "presentation.controller"})
public class DemoApplication {

  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }

}


11 「http://localhost:8080/tasks」 にアクセス

・「/tasks」はすべてのエンティティを返却する(多分select * from ~)

返却されたレスポンス
[
    {
        "id": 1,
        "taskName": "tast",
        "scheduledCompletionOn": "2024-06-03T07:25:00",
        "isComplete": 0,
        "createdAt": "2024-06-03T07:25:00",
        "updatedAt": "2024-06-03T07:25:00"
    },
    {
        "id": 2,
        "taskName": "tast",
        "scheduledCompletionOn": "2024-06-03T07:25:00",
        "isComplete": 0,
        "createdAt": "2024-06-03T07:25:00",
        "updatedAt": "2024-06-03T07:25:00"
    },
    {
        "id": 3,
        "taskName": "tast",
        "scheduledCompletionOn": "2024-06-03T07:25:00",
        "isComplete": 0,
        "createdAt": "2024-06-03T07:25:00",
        "updatedAt": "2024-06-03T07:25:00"
    },
    {
        "id": 4,
        "taskName": "tast",
        "scheduledCompletionOn": "2024-06-03T07:25:00",
        "isComplete": 0,
        "createdAt": "2024-06-03T07:25:00",
        "updatedAt": "2024-06-03T07:25:00"
    },
    {
        "id": 5,
        "taskName": "tast",
        "scheduledCompletionOn": "2024-06-03T07:25:00",
        "isComplete": 0,
        "createdAt": "2024-06-03T07:25:00",
        "updatedAt": "2024-06-03T07:25:00"
    }
]

用語

用語の説明
ライブラリ名 説明 備考
ORM Object-Relational Mappingの略。JavaのオブジェクトとDBのテーブルをクラスでマッピングすること

Discussion