# 機能設計書 18-コード生成

## 概要

本ドキュメントは、RuoYiシステムにおけるコード生成機能の詳細設計を記述する。コード生成機能は、データベースのテーブル構造からCRUD操作に必要なJavaコード、MyBatis Mapper、HTML画面テンプレートを自動生成する開発支援ツールである。

### 本機能の処理概要

コード生成機能は、データベーステーブルの情報を読み取り、テンプレートエンジン（Velocity）を使用してドメインクラス、Mapper、Service、Controller、HTML画面などのソースコードを一括生成する機能を提供する。

**業務上の目的・背景**：業務アプリケーション開発では、CRUD操作のための定型的なコードが大量に必要となる。これらを手作業で作成すると、工数がかかる上にミスが発生しやすい。コード生成機能により、テーブル定義からコードを自動生成することで、開発効率を大幅に向上させ、コード品質の均一化を図ることができる。

**機能の利用シーン**：
- 新規テーブルを作成し、対応するCRUD機能を実装する際
- 既存テーブルの構造変更をコードに反映する際
- 生成されるコードをプレビューで確認する際
- 単表/ツリー表/主従表の各パターンのコードを生成する際

**主要な処理内容**：
1. コード生成対象テーブル一覧の表示
2. データベーステーブルのインポート
3. SQL文からのテーブル作成とインポート
4. テーブル設定の編集（生成オプション、カラム設定など）
5. コードのプレビュー表示
6. コードの生成（ZIP形式ダウンロード/ローカル出力）
7. データベースとの同期（テーブル構造変更の反映）

**関連システム・外部連携**：データベースメタデータ、Velocityテンプレートエンジンと連携。

**権限による制御**：
- `tool:gen:view` - コード生成画面の閲覧
- `tool:gen:list` - テーブル一覧の取得
- `tool:gen:edit` - テーブル設定の編集
- `tool:gen:remove` - テーブルの削除
- `tool:gen:preview` - コードのプレビュー
- `tool:gen:code` - コードの生成
- `admin` ロール - テーブル作成（SQL実行）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 63 | フォームビルダー | 補助画面 | ドラッグ&ドロップによるフォーム作成ツール |
| 64 | コード生成一覧 | 主画面 | テーブル一覧表示、プレビュー、コード生成、DB同期処理 |
| 65 | テーブルインポート | インポート画面 | データベーステーブルのインポート処理 |
| 66 | テーブル作成 | 作成画面 | 新規テーブル作成のSQL実行処理 |
| 67 | コード生成編集 | 編集画面 | コード生成設定の編集保存処理 |

## 機能種別

コード生成 / CRUD操作 / データベースメタデータ操作

## 入力仕様

### 入力パラメータ

#### テーブルインポート

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| tables | String | Yes | インポート対象テーブル名（カンマ区切り） | 存在するテーブル名 |

#### テーブル作成

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| sql | String | Yes | CREATE TABLE文 | 有効なMySQL CREATE文 |

#### テーブル編集

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| tableId | Long | Yes | テーブルID | 存在するID |
| tableName | String | Yes | テーブル名 | 空白不可 |
| tableComment | String | Yes | テーブルコメント | 空白不可 |
| className | String | Yes | クラス名 | 空白不可 |
| packageName | String | Yes | パッケージ名 | 空白不可 |
| moduleName | String | Yes | モジュール名 | 空白不可 |
| businessName | String | Yes | ビジネス名 | 空白不可 |
| functionName | String | Yes | 機能名 | 空白不可 |
| functionAuthor | String | Yes | 作者名 | 空白不可 |
| tplCategory | String | No | テンプレート種別 | crud/tree/sub |
| genType | String | No | 生成方式 | 0:ZIP、1:ローカル |
| columns | List | Yes | カラム情報リスト | 有効なカラム設定 |

### 入力データソース

- データベースメタデータ（INFORMATION_SCHEMA）
- DBテーブル gen_table, gen_table_column
- 画面入力

## 出力仕様

### 出力データ

#### テーブル一覧

| 項目名 | 型 | 説明 |
|--------|-----|------|
| tableId | Long | テーブルID |
| tableName | String | テーブル名 |
| tableComment | String | テーブルコメント |
| className | String | クラス名 |
| packageName | String | パッケージ名 |
| createTime | Date | 作成日時 |
| updateTime | Date | 更新日時 |

#### 生成コード

| 出力ファイル | 説明 |
|-------------|------|
| domain/*.java | エンティティクラス |
| mapper/*Mapper.java | Mapperインターフェース |
| mapper/*Mapper.xml | MyBatis XMLマッピング |
| service/I*Service.java | サービスインターフェース |
| service/impl/*ServiceImpl.java | サービス実装 |
| controller/*Controller.java | コントローラー |
| *.html | 画面テンプレート（list, add, edit） |
| sql/*.sql | メニュー登録SQL |

### 出力先

- ZIPファイルダウンロード
- ローカルファイルシステム（genPath指定時）

## 処理フロー

### 処理シーケンス

```
1. テーブル一覧表示
   └─ gen_tableからインポート済みテーブル一覧を取得

2. テーブルインポート
   └─ データベースからテーブル・カラム情報を取得
   └─ gen_table, gen_table_columnに保存
   └─ 初期設定（パッケージ名、クラス名等）を自動生成

3. テーブル作成
   └─ CREATE TABLE SQLを解析
   └─ SQLを実行してテーブル作成
   └─ 自動的にインポート処理を実行

4. コードプレビュー
   └─ gen_tableからテーブル情報を取得
   └─ Velocityテンプレートにデータをバインド
   └─ 各テンプレートのレンダリング結果をMapで返却

5. コード生成
   └─ gen_tableからテーブル情報を取得
   └─ Velocityテンプレートでコード生成
   └─ ZIPまたはローカルファイルに出力

6. DB同期
   └─ データベースの現在のカラム情報を取得
   └─ gen_table_columnと比較
   └─ 追加カラム→INSERT、削除カラム→DELETE、変更カラム→UPDATE
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{操作種別}
    B -->|インポート| C[テーブル名受付]
    C --> D[DBメタデータ取得]
    D --> E[gen_table/columnに保存]
    E --> F[成功返却]

    B -->|作成| G[SQL受付]
    G --> H[SQL解析・検証]
    H --> I[CREATE TABLE実行]
    I --> J[テーブルインポート]
    J --> K[成功返却]

    B -->|プレビュー| L[tableId受付]
    L --> M[テーブル情報取得]
    M --> N[Velocityレンダリング]
    N --> O[プレビュー返却]

    B -->|生成| P[tableName受付]
    P --> Q[テーブル情報取得]
    Q --> R[Velocityレンダリング]
    R --> S{生成方式}
    S -->|ZIP| T[ZIPダウンロード]
    S -->|ローカル| U[ファイル出力]

    B -->|DB同期| V[tableName受付]
    V --> W[DBメタデータ取得]
    W --> X[差分検出]
    X --> Y[gen_table_column更新]
    Y --> Z[成功返却]

    F --> AA[終了]
    K --> AA
    O --> AA
    T --> AA
    U --> AA
    Z --> AA
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-18-01 | 上書き禁止設定 | GenConfig.isAllowOverwrite()がfalseの場合、ローカル出力禁止 | genType=1の時 |
| BR-18-02 | テンプレート種別 | crud（単表）/tree（ツリー表）/sub（主従表）から選択 | テーブル編集時 |
| BR-18-03 | SQLフィルタリング | 危険なキーワード（DROP, TRUNCATE等）をブロック | SQL実行時 |
| BR-18-04 | テーブル作成権限 | admin ロールのみSQL実行可能 | テーブル作成時 |
| BR-18-05 | 自動命名 | テーブル名からクラス名、ビジネス名を自動生成 | インポート時 |

### 計算ロジック

特になし

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 一覧取得 | gen_table | SELECT | インポート済みテーブル一覧 |
| DBテーブル一覧 | INFORMATION_SCHEMA.TABLES | SELECT | データベースのテーブル一覧 |
| インポート | gen_table, gen_table_column | INSERT | テーブル・カラム情報を保存 |
| 編集 | gen_table, gen_table_column | UPDATE | 設定情報を更新 |
| 削除 | gen_table, gen_table_column | DELETE | テーブル・カラム情報を削除 |
| DB同期 | gen_table_column | INSERT/UPDATE/DELETE | カラム情報を同期 |
| テーブル作成 | 指定テーブル | CREATE | 新規テーブル作成 |

### テーブル別操作詳細

#### gen_table

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | table_name, table_comment, class_name, package_name, module_name, business_name, function_name, function_author, tpl_category, gen_type, gen_path, options | 入力値/自動生成値 | インポート時 |
| UPDATE | 同上 | 入力値 | 編集時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 上書き禁止エラー | ローカル出力時にisAllowOverwrite=false | 設定変更またはZIP方式を使用 |
| - | SQLエラー | 無効なSQL文 | SQL文を修正 |
| - | テーブル存在エラー | 既に存在するテーブル名でCREATE | テーブル名を変更 |
| - | 権限エラー | 必要な権限がない場合 | 適切な権限を付与 |

### リトライ仕様

特になし

## トランザクション仕様

- インポート/編集/削除/DB同期はトランザクション管理下で実行
- コード生成自体はデータベース変更を伴わない

## パフォーマンス要件

- テーブル一覧：1秒以内
- インポート：テーブルあたり500ms以内
- コード生成：テーブルあたり1秒以内

## セキュリティ考慮事項

- Apache Shiroによる権限制御
- admin ロール制限によるSQL実行制御
- SqlUtil.filterKeyword()による危険なSQLキーワードの検出
- 操作ログの記録（@Logアノテーション）

## 備考

- Velocityテンプレートはruoyi-generator/src/main/resources/vm/配下に格納
- 生成コードはRuoYiフレームワークの規約に従った構造
- 主従表テンプレートは親子テーブルの関連設定が必要

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、コード生成のデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | GenTable.java | `ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java` | テーブル情報のエンティティ。tplCategory, genType, オプション設定に注目 |
| 1-2 | GenTableColumn.java | `ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java` | カラム情報のエンティティ。Java型、HTMLタイプ、クエリ方式など |
| 1-3 | GenConstants.java | `ruoyi-common/src/main/java/com/ruoyi/common/constant/GenConstants.java` | コード生成の定数定義 |

**読解のコツ**: GenTableにはisSub(), isTree(), isCrud()メソッドがあり、テンプレート種別の判定に使用される。

#### Step 2: エントリーポイントを理解する

コントローラーが処理の起点となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | GenController.java | `ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java` | 各エンドポイントの定義と権限設定 |

**主要処理フロー**:
- **68-76行目**: genList() - インポート済みテーブル一覧
- **81-89行目**: dataList() - DBテーブル一覧（インポート対象）
- **128-140行目**: importTableSave() - テーブルインポート
- **197-228行目**: create() - テーブル作成（SQL実行）
- **233-240行目**: preview() - コードプレビュー
- **257-269行目**: genCode() - コード生成（ローカル）
- **247-252行目**: download() - コード生成（ZIP）
- **274-282行目**: synchDb() - DB同期

#### Step 3: サービス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | IGenTableService.java | `ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java` | サービスインターフェース定義 |
| 3-2 | GenTableServiceImpl.java | `ruoyi-generator/src/main/java/com/ruoyi/generator/service/impl/GenTableServiceImpl.java` | サービス実装、Velocity連携ロジック |

#### Step 4: ユーティリティを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | GenUtils.java | `ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java` | テーブル/カラム情報の初期化ロジック |
| 4-2 | VelocityUtils.java | `ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java` | Velocityテンプレート処理 |

### プログラム呼び出し階層図

```
GenController
    │
    ├─ genList()
    │      └─ IGenTableService.selectGenTableList()
    │             └─ GenTableMapper.selectGenTableList()
    │
    ├─ importTableSave()
    │      ├─ IGenTableService.selectDbTableListByNames()
    │      │      └─ GenTableMapper.selectDbTableListByNames()
    │      │
    │      └─ IGenTableService.importGenTable()
    │             ├─ GenUtils.initTable()
    │             ├─ GenTableMapper.insertGenTable()
    │             ├─ GenUtils.initColumnField()
    │             └─ GenTableColumnMapper.insertGenTableColumn()
    │
    ├─ preview()
    │      └─ IGenTableService.previewCode()
    │             ├─ selectGenTableById()
    │             ├─ VelocityUtils.prepareContext()
    │             └─ Velocity.render() [各テンプレート]
    │
    ├─ download() / genCode()
    │      └─ IGenTableService.downloadCode() / generatorCode()
    │             ├─ selectGenTableByName()
    │             ├─ VelocityUtils.prepareContext()
    │             ├─ VelocityUtils.getTemplateList()
    │             └─ [各テンプレートのレンダリング・出力]
    │
    └─ synchDb()
           └─ IGenTableService.synchDb()
                  ├─ selectDbTableColumnsByName()
                  ├─ selectGenTableColumnListByTableId()
                  └─ [差分比較・更新]
```

### データフロー図

```
[入力]               [処理]                    [出力]

テーブル名    ───▶ Controller         ───▶ gen_table
                   ↓                        gen_table_column
                   selectDbTableListByNames
                   ↓
                   INFORMATION_SCHEMA
                   ↓
                   GenUtils.initTable/Column
                   ↓
                   INSERT

tableId      ───▶ Controller         ───▶ Map<String, String>
                   ↓                        (コードプレビュー)
                   selectGenTableById
                   ↓
                   VelocityUtils
                   ↓
                   Velocity Templates
                   ↓
                   render()

tableName    ───▶ Controller         ───▶ ZIP / ファイル
                   ↓                        (生成コード)
                   selectGenTableByName
                   ↓
                   VelocityUtils
                   ↓
                   render() + 出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| GenController.java | `ruoyi-generator/src/main/java/com/ruoyi/generator/controller/` | コントローラー | HTTPリクエストのハンドリング |
| GenTable.java | `ruoyi-generator/src/main/java/com/ruoyi/generator/domain/` | エンティティ | テーブル情報モデル |
| GenTableColumn.java | `ruoyi-generator/src/main/java/com/ruoyi/generator/domain/` | エンティティ | カラム情報モデル |
| IGenTableService.java | `ruoyi-generator/src/main/java/com/ruoyi/generator/service/` | インターフェース | サービス層の契約定義 |
| GenTableServiceImpl.java | `ruoyi-generator/src/main/java/com/ruoyi/generator/service/impl/` | サービス実装 | ビジネスロジック |
| GenTableMapper.java | `ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/` | Mapper | データアクセス層 |
| GenUtils.java | `ruoyi-generator/src/main/java/com/ruoyi/generator/util/` | ユーティリティ | テーブル/カラム初期化 |
| VelocityUtils.java | `ruoyi-generator/src/main/java/com/ruoyi/generator/util/` | ユーティリティ | Velocityテンプレート処理 |
| GenConfig.java | `ruoyi-generator/src/main/java/com/ruoyi/generator/config/` | 設定 | コード生成設定 |
| vm/*.vm | `ruoyi-generator/src/main/resources/vm/` | テンプレート | Velocityテンプレート |
