😸
SpringBootでアプリ作ってみる1️⃣(DBリクエストでDBの値を取得まで)
目次
- 目次
- 1 Pleades(STS)をDL
- 2 プロジェクト作成
- 3 DockerでMySQLを起動
- 4 DB定義
- 5 DB設定(アプリ)
- 6 エンティティ作成
- 7 エンティティ作成
- 8 サービス作成
- 9 コントローラ作成
- 10 エントリークラスを作成
- 11 「http://localhost:8080/tasks」 にアクセス
- 用語
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オプションの利用目的
- データ永続化
- バインドマウント
- ボリューム
「ホストのディレクトリ」や「新たに作成したボリューム」をマウントすることでデータを永続化させる- ホストのディレクトリ
「-v ホストマシンのディレクトリ:Dockerコンテナのディレクトリ」
ディレクトリを共有するので見やすいが、権限の関係で起動しないこともあるみたい
https://qiita.com/ysd_marrrr/items/e8a50c43cff87951385c
例)Windowsの場合「-v c/dev:/var/lib/mysql」 - 新たに作成したボリューム
推奨。Dockerのコマンドでボリュームを作成→それをマウントの流れ
https://zenn.dev/satonopan/articles/43ba26f97a8388
「-v vol1:/tmp/volume」
- ホストのディレクトリ
- データの共有
- 複数のコンテナで同じホスト先のフォルダをマウントすれば、複数コンテナ内でのデータの共有ができる
- 設定ファイルの受け渡し
- 設定ファイルをマウントしておくと、その設定を変えるだけでコンテナの設定を変更できる
用語
- マウント
「対象」を接続して、OS・アプリが操作できるようにすること。
例)パソコンにマウスを接続して、OSがマウスを操作できるようにする。 - ボリューム
外部記憶装置のこと
例)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);
}
}
http://localhost:8080/tasks」 にアクセス
11 「・「/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