Beginner's Hack

復習用。誰かのためになれば...

ポートフォリオを計画的に作成するために

エンジニアとして働きたいなら避けては通れないポートフォリオ制作。
私も独学でphpを学習した後に簡単なSNSサイトを作成してみましたが、散々な出来栄えだった…

何も考えずコード書き始めたせいで、
実装し始めてから「なにかイメージと違う」となって書き直したり、
次々と新しい機能を付け足した挙句、結局完成せず…まるでサクラダファミリア。

この度、再度ポートフォリオ作成にチャレンジしようと思ったので、
要件定義について調べたことをメモ。

要件定義の3つのステップ

要件定義の説明をするにあたり、「要件」と似た「要望」「要求」という2つの言葉も交えて説明。

  • 要望:ユーザーの願望(〇〇だといいな)
  • 要求:要望を具体的に表したもの(□□を△△したい)
  • 要件:要求を解決するためのプロダクトやサービスの案

さらに「定義」という言葉を「明確にする」という風に読み替えると以下の3ステップに分解可能。

  1. ヒアリング:ユーザーの要望を確認する
  2. 要求定義:要望を明確化する
  3. 要件定義:要求を解決する策を明確化する

ヒヤリング

ポートフォリオ作成では自身の要望や、周囲の人の要望からテーマを決める。

要求定義

要望を5W1Hで明確化する。

  • What: 求めるもの
  • Who: 求めている人
  • Why: なぜ必要なのか
  • Where: どこで使うのか
  • When: いつ使うのか
  • How: どのように使うのか

要件定義

要求を解決する策を5W1Hで明確化する。

  • What: どういった機能を実装するのか
  • Who: 誰が行うのか
  • Why: なぜその機能が必要なのか
  • Where: どこまで作るのか(完成度)
  • When: いつまでに作るのか(納期)
  • How: どのように実現するのか(言語やライブラリ)

要件定義を始める前に

まずは現状を正確に把握すること。 要求に対して正しい要件を定義できなければ、独りよがりなプロダクトになってしまう恐れがある。

その他使えるツール

  • 用語集:複数人で設計を開発を行う際に認識のズレを起こさないためにも必要

ループ処理の書き方[Java]

Javaでループ処理を書くとき、どの書き方を使おうか迷った為、メモ

ループ処理の種類

命令型

  • for文
for (int i = 0; i < somethings.size(); i++) {
  doSomething();
}
  • 拡張for文
for (Something something : somethings) {
 doSomething();

関数型

  • forEach
somethings.forEach(something -> doSomething());
  • stream
somethings.stream().map(something -> doSomething()).collect(Collectors.toList);

感想

  • for文:カウンタ使いたい
  • 拡張for文:カウンタ使いたい
  • forEach:型の宣言がいらない分、拡張forより優秀
  • stream:filter()などの中間操作が目的と一致していればコードを減らせる

特に理由がなければ、関数型の記述を心がけたい。

SpringBootアプリケーション開発の始め方

概要

前回作成したDocker環境でSpringBootプロジェクトの開発を始める手順をまとめる

この記事の対象者

開発環境はあるが、SpringBootプロジェクトの開発方法が分からない方
↓開発環境を作りたい方はこちらをどうぞ↓
VSCode + DockerでSpringBoot開発環境の構築 - Beginner's Hack

この記事の目的

localhostにアクセスしたら、"Hello World"出力されるようになる。

コード置き場

github.com

手順

SpringBootプロジェクトを作成する

今回はSpring Initializerでプロジェクトを作成する。
*他にもSTSVSCodeの機能を使用して作成することも可能

Spring Initializerにアクセスすると下のようなページが表示される。

Spring Initializer

注意点はJavaのバージョンが、使用するJDKのバージョンとあっていること。
画面左側については、こだわりがなければ画面通りで大丈夫。

画面右側の"ADD DEPENDENCIES"を押して Spring Webを追加する。
これで"GENERATE"を推すとプロジェクトがzip形式で保存される。
zipファイルを展開して、Dockerでコンテナにマウントするディレクトリに保存すれば準備はOK。
Dockerコンテナを使用しない(STSeclipse等を使用する)場合は任意の場所でOK。

コードを書いていく

画面の様にフォルダを辿っていくと、xxxApplication.javaというファイルがある。

Application.java

このxxxApplication.javaと同じ階層にcontrollerフォルダを作成し、
フォルダの中にxxxController.javaファイルを作成する。
xxxApplication.javaが作成できたら、下記のコードを記述する。

package com.example.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {
  
  @RequestMapping("/")
    String hello() {
        return "Hello World!!";
    }
}

@RestControllerや@RequestMappingは、
先ほどのプロジェクト作成の際に追加したSpring Webの機能である。

実行する

プロジェクトを実行し、localhostにアクセスすれば"Hello World"と出力されている。

Gradleプロジェクトでビルドエラー with SpringDataJPA

概要

Gradleプロジェクトをビルドした際に発生したエラーと対応についてまとめる。

事象

Spring Initializerで作成したGradleプロジェクトでビルドエラーが発生

# コンソール
$ gradlew build
:
:
略
:
:
> Task :test

DemoGApplicationTests > contextLoads() FAILED
    java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:132
        Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:800
            Caused by: org.springframework.beans.factory.BeanCreationException at ConstructorResolver.java:658
                Caused by: org.springframework.beans.BeanInstantiationException at SimpleInstantiationStrategy.java:185
                    Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException at DataSourceProperties.java:252

1 test completed, 1 failed
# /build/reports/tests/test/index.html

Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class

原因の推測

Spring Initializerでプロジェクトを作成した際に、Spring Data JPAを追加しているにも関わらず、 ドライバーの追加とapplication.propertiesの記載が抜けている。

対処

build.gradleにmysqlのドライバーの追加と、application.propertiesへの設定の追記を行なった。

# build.gradle
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    runtimeOnly 'mysql:mysql-connector-java' # 追加
}

# application.properties
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://mysql/sample_schema
spring.datasource.username="自身の設定に合わせる"
spring.datasource.password="自身の設定に合わせる"
spring.jpa.database=”自身の設定に合わせる”

環境

  • docker

VSCode + DockerでSpringBoot開発環境の構築

概要

VSCodeとDockerを使用したSpringBootの開発環境の構築手順を記す。

この記事の対象者

Spring Bootの開発やデバッグを行いたいが、
MacIDEやDBをインストールしたくない方。

この記事の目的

VSCodeのRemote-Containerを使用して、
Docker上のJavaコンテナ内でコードを編集、実行できるようにする。

コード

github.com

解説

DockerでJavaコンテナ(+α)を立ち上げる

必要なファイルの作成

workspace
  |-docker
      |- docker-compose.yml
      |- mysql
           |- sql_init:起動時に実行されるSQL文
           |- db.env:DB設定の記述(DB名、パスワード等)
           |- Dockerfile:使用するイメージの指定やmy.cnf(設定ファイル)のコピーなどを記述
           |- my.cnf:文字コード等

/mysqlの中身はgithub参照

docker-compose.ymlの記述

services:
  java:
    image: openjdk:15
    container_name: java
    env_file:
      - ./mysql/db.env # mysqlと同じものを指定
    tty: true
    working_dir: /app #コンテナ内のワーキングディレクトリ
    volumes:
      - type: bind # source(ホストマシン)のディレクトリをtarget(コンテナ)にマウントする
        source: ../spring_prj
        target: /app
    ports:
      - 8080:8080 # 通常実行
      - 5050:5050 # デバッグ用
    depends_on:
      - mysql # 「mysql」の後で起動

  mysql:
    # imageの指定ではなく、Dockerfileを用意している。
    # 理由:ビルドの過程で必要な情報を読み取ることが可能。
    # 補足:docker-compose.ymlではビルド後にコンテナへマウントする。
    build: ./mysql
    container_name: mysql
    env_file:
      - ./mysql/db.env #MySQLの設定ファイル
    volumes:
      - mysql_data:/var/lib/mysql #実データの永読化
      - ./mysql/log:/var/log/mysql #logの永読化
      - ./mysql/sql_init:/docker-entrypoint-initdb.d
    ports:
      - 3306:3306

volumes:
  mysql_data:
    name: spring_boot_mysql

一度コンテナが起動できるか確認しておく

コンテナ起動
$ docker-compose up -d


コンテナ停止、削除
$ docker-compose down

Remote-Containersを使用する為のファイルの作成

workspace
  |- docker
  |- .devcontainer #新規作成
          |- devcontainer.json #新規作成

devcontainer.jsonの記述

{
  // 任意の名前
  "name": "remote-java",
  // DockerComposeFileを指定
  "dockerComposeFile": "../docker/docker-compose.yml",
  // DockerComposeFileにあるservice名を指定
  "service": "java",
  // コンテナに入ったときの作業ディレクトリ
  "workspaceFolder": "/app",
  "settings": {
      // bashでターミナルを起動
      "terminal.integrated.defaultProfile.linux": "bash"
  },
  // コンテナ内で使いたい拡張機能
  "extensions": [
    // Java関連の拡張機能パック
    "vscjava.vscode-java-pack",
    // Spring Boot関連の拡張機能パック
    "pivotal.vscode-boot-dev-pack",
    "gabrielbb.vscode-lombok",
  ]
}

Remote-Containers起動

  1. VSCode画面左下にある「><」マークを選択。
  2. コマンド一覧から「Reopen in Container」を実行。
    Remote-Container起動

環境

  • macOS Monterey
  • Docker 20.10.8