0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

販売管理システムのケーススタディ 第2章: 開発環境の構築

0
Last updated at Posted at 2025-12-01

目次

第2章: 開発環境の構築

2.1 技術スタックの選定

Java 25 を選んだ理由

本プロジェクトでは、バックエンド言語として Java 25 を採用しています。Java を選んだ主な理由は以下の通りです。

観点 Java の利点
型安全性 コンパイル時のエラー検出で堅牢なコードを実現
エコシステム Spring Boot、MyBatis など成熟したフレームワーク群
保守性 静的型付けにより、大規模コードベースでもリファクタリングが安全
テスト JUnit 5、Mockito など充実したテストツール
ドキュメント生成 JIG、JIG-ERD によるアーキテクチャ図の自動生成

Spring Boot の利点

Spring Boot は Java の Web アプリケーション開発において最も広く使われているフレームワークです。

Spring Boot の主な特徴

特徴 説明
自動設定 設定より規約(Convention over Configuration)で開発効率向上
組み込みサーバー Tomcat が組み込まれ、単独で実行可能な JAR を生成
スターター 依存関係をスターターで一括管理
Actuator ヘルスチェック、メトリクスなど運用機能を標準提供
DevTools ホットリロードによる開発効率向上

MyBatis vs JPA の選択

O/R マッパーとして MyBatis を採用しました。

MyBatis を選んだ理由

観点 MyBatis の利点
SQL 制御 複雑な SQL を直接記述でき、パフォーマンスチューニングが容易
学習コスト SQL の知識がそのまま活用でき、学習曲線が緩やか
デバッグ 実行される SQL が明確で、問題の特定が容易
柔軟性 動的 SQL により、条件に応じた柔軟なクエリが記述可能
既存 DB 対応 既存データベースへの適用が容易
// MyBatis Mapper の例
public interface ProductMapper {
    @Select("SELECT * FROM products WHERE product_code = #{productCode}")
    Product findByProductCode(String productCode);

    @Insert("INSERT INTO products (product_code, product_name, price) " +
            "VALUES (#{productCode}, #{productName}, #{price})")
    void insert(Product product);
}

2.2 バックエンド環境

Gradle プロジェクトのセットアップ

本プロジェクトでは Gradle をビルドツールとして使用しています。

build.gradle の構成

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.5.0-SNAPSHOT'
    id 'io.spring.dependency-management' version '1.1.6'
    id 'org.dddjava.jig-gradle-plugin' version '2025.10.1'
    id 'org.flywaydb.flyway' version '11.15.0'
    id 'com.thinkimi.gradle.MybatisGenerator' version '2.4'
    id 'jacoco'
    id 'org.sonarqube' version '7.0.1.6134'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(25)
    }
}

主要な依存関係

dependencies {
    // Spring Boot スターター
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

    // MyBatis
    implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'

    // データベース
    runtimeOnly 'com.h2database:h2'
    runtimeOnly 'com.mysql:mysql-connector-j'
    runtimeOnly 'org.postgresql:postgresql'

    // Flyway
    implementation 'org.flywaydb:flyway-core:11.15.0'

    // JWT
    implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
    runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.5'

    // テスト
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'io.cucumber:cucumber-java:7.18.0'
    testImplementation 'io.cucumber:cucumber-spring:7.18.1'
}

Spring Boot アプリケーションの初期化

アプリケーションクラス

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

設定ファイル(application.yml)

spring:
  datasource:
    url: jdbc:h2:mem:testdb
    driver-class-name: org.h2.Driver
    username: sa
    password:
  h2:
    console:
      enabled: true
      path: /h2-console
  flyway:
    enabled: true
    locations: classpath:db/migration/h2

mybatis:
  mapper-locations: classpath:mapper/**/*.xml
  configuration:
    map-underscore-to-camel-case: true

server:
  port: 8080

MyBatis Generator の設定

MyBatis Generator を使用してデータベースからマッパーを自動生成します。

<!-- generatorConfig.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC
        "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <context id="default" targetRuntime="MyBatis3">
        <jdbcConnection driverClass="org.h2.Driver"
                        connectionURL="jdbc:h2:mem:testdb"
                        userId="sa"
                        password="">
        </jdbcConnection>

        <javaModelGenerator targetPackage="com.example.sms.infrastructure.datasource.autogen.model"
                            targetProject="src/main/java"/>

        <sqlMapGenerator targetPackage="mapper.autogen"
                         targetProject="src/main/resources"/>

        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.example.sms.infrastructure.datasource.autogen.mapper"
                             targetProject="src/main/java"/>

        <table tableName="%" />
    </context>
</generatorConfiguration>

Flyway によるマイグレーション管理

データベーススキーマのバージョン管理に Flyway を使用しています。

マイグレーションファイルの命名規則

V{version}__{description}.sql

例:
V1__create_users_table.sql
V2__create_departments_table.sql
V3__create_employees_table.sql

マイグレーションファイルの例

-- V1__create_users_table.sql
CREATE TABLE usr (
    user_id VARCHAR(255) PRIMARY KEY,
    first_name VARCHAR(100) NOT NULL,
    last_name VARCHAR(100) NOT NULL,
    password VARCHAR(255) NOT NULL,
    role_name VARCHAR(50) NOT NULL
);

-- V2__create_departments_table.sql
CREATE TABLE department (
    department_id VARCHAR(255) PRIMARY KEY,
    department_code VARCHAR(10) NOT NULL UNIQUE,
    department_name VARCHAR(100) NOT NULL,
    start_date DATE,
    end_date DATE,
    path VARCHAR(500)
);

2.3 フロントエンド環境

Vite + React + TypeScript

フロントエンドは Vite をビルドツールとして、React + TypeScript で構築しています。

package.json の構成

{
  "name": "app",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "test": "jest",
    "lint": "eslint .",
    "cypress:open": "cypress open",
    "cypress:run": "cypress run"
  },
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-router-dom": "^6.26.2",
    "react-modal": "^3.16.1",
    "react-tabs": "^6.0.2"
  },
  "devDependencies": {
    "@vitejs/plugin-react": "^4.3.1",
    "typescript": "^5.5.3",
    "vite": "^5.4.1",
    "jest": "^29.7.0",
    "cypress": "^14.5.1"
  }
}

開発サーバーの設定

vite.config.ts

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  server: {
    port: 3000,
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
      },
    },
  },
});

API クライアントの構成

バックエンド API との通信を担う API クライアントを実装しています。

// api/client.ts
const API_BASE_URL = '/api';

export const apiClient = {
  async get<T>(path: string): Promise<T> {
    const response = await fetch(`${API_BASE_URL}${path}`, {
      headers: {
        'Authorization': `Bearer ${getToken()}`,
      },
    });
    if (!response.ok) throw new Error('API Error');
    return response.json();
  },

  async post<T>(path: string, data: unknown): Promise<T> {
    const response = await fetch(`${API_BASE_URL}${path}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${getToken()}`,
      },
      body: JSON.stringify(data),
    });
    if (!response.ok) throw new Error('API Error');
    return response.json();
  },
};

2.4 開発ツール

JIG によるアーキテクチャドキュメント生成

JIG は、Java ソースコードからアーキテクチャドキュメントを自動生成するツールです。

JIG の実行

./gradlew jigReports

生成されるドキュメント

ファイル 内容
application.html サービス層のメソッド一覧
architecture.svg レイヤー間の依存関係図
business-rule.xlsx ビジネスルール(値オブジェクト、列挙型)一覧
composite-usecase.svg ユースケース複合図
domain.html ドメインモデル一覧
term.html 用語集

JIG-ERD による ER 図自動生成

JIG-ERD は、ER 図を自動生成するツールです。

// テストコードで ER 図を生成
@Test
void generateErDiagram() {
    var output = Path.of("build/jig-erd");
    var packageName = "com.example.sms.infrastructure.datasource";

    JigErd.run(output, packageName);
}

生成される ER 図

ファイル 内容
library-er-overview.svg 概要 ER 図(テーブル名のみ)
library-er-summary.svg サマリー ER 図(主要カラム)
library-er-detail.svg 詳細 ER 図(全カラム)

SonarQube によるコード品質管理

SonarQube を使用してコード品質を継続的に分析しています。

分析項目

項目 説明
バグ 潜在的なバグの検出
脆弱性 セキュリティ上の問題
コードスメル 保守性を低下させるコード
カバレッジ テストカバレッジ
重複 コードの重複率

ArchUnit によるアーキテクチャテスト

ArchUnit を使用してアーキテクチャルールをテストとして検証しています。

@AnalyzeClasses(packages = "com.example.sms")
public class ArchitectureTest {

    @ArchTest
    static final ArchRule layer_dependencies = layeredArchitecture()
        .consideringAllDependencies()
        .layer("Presentation").definedBy("..presentation..")
        .layer("Service").definedBy("..service..")
        .layer("Domain").definedBy("..domain..")
        .layer("Infrastructure").definedBy("..infrastructure..")
        .whereLayer("Presentation").mayOnlyBeAccessedByLayers()
        .whereLayer("Service").mayOnlyBeAccessedByLayers("Presentation")
        .whereLayer("Domain").mayOnlyBeAccessedByLayers("Service", "Infrastructure")
        .whereLayer("Infrastructure").mayNotBeAccessedByAnyLayer();

    @ArchTest
    static final ArchRule controllers_should_be_in_presentation_layer =
        classes()
            .that().haveSimpleNameEndingWith("Controller")
            .should().resideInAPackage("..presentation..");
}

2.5 CI/CD パイプライン

GitHub Actions の構成

本プロジェクトでは GitHub Actions を使用して CI/CD を実現しています。

# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Set up JDK 25
      uses: actions/setup-java@v4
      with:
        java-version: '25'
        distribution: 'temurin'

    - name: Setup Gradle
      uses: gradle/gradle-build-action@v3

    - name: Build with Gradle
      run: ./gradlew build
      working-directory: app/backend/sms

    - name: Run tests
      run: ./gradlew test
      working-directory: app/backend/sms

    - name: Generate JIG reports
      run: ./gradlew jigReports
      working-directory: app/backend/sms

    - name: Upload JIG reports
      uses: actions/upload-artifact@v4
      with:
        name: jig-reports
        path: app/backend/sms/build/jig

テスト自動化

テストの階層

テスト種別 ツール 対象
単体テスト JUnit 5, Mockito ドメインモデル、サービス
統合テスト Spring Boot Test コントローラ、リポジトリ
受け入れテスト Cucumber ユースケースシナリオ
E2E テスト Cypress 画面操作シナリオ

デプロイメント戦略

環境構成


まとめ

本章では、開発環境の構築について解説しました。

  • バックエンド: Java 25 + Spring Boot + MyBatis + Gradle
  • フロントエンド: React + TypeScript + Vite
  • データベース: H2(開発)/ MySQL / PostgreSQL(本番)+ Flyway
  • 品質管理: JIG、JIG-ERD、SonarQube、ArchUnit
  • CI/CD: GitHub Actions による自動化

次章では、本システムのアーキテクチャ設計について詳しく解説します。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?