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

## はじめに

このガイドラインは、RuoYi（若依）管理システムのコードベースを効率的に理解するための手引きです。
Javaに精通していないエンジニアでも、段階的に学習できるよう構成されています。

**対象読者:**
- プロジェクトに新規参画するエンジニア
- 他言語からの経験者
- コードレビューを行う担当者

**プロジェクト概要:**
- バージョン: 4.8.2
- 言語: Java 1.8
- フレームワーク: Spring Boot 2.5.15
- セキュリティ: Apache Shiro 1.13.0
- テンプレートエンジン: Thymeleaf
- ORM: MyBatis
- データベース: MySQL

---

## 1. 言語基礎

> このセクションでは、Javaの基本構文と概念を解説します。

### 1.1 プログラム構造

Javaプログラムはクラスを基本単位として構成されます。RuoYiでは標準的なSpring Bootアプリケーション構造を採用しています。

**エントリーポイントの例:**
```java
// ファイル: ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java:12-19
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class RuoYiApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(RuoYiApplication.class, args);
    }
}
```

**解説:**
- `@SpringBootApplication`: Spring Bootアプリケーションであることを示すアノテーション
- `main`メソッド: アプリケーションのエントリーポイント
- `SpringApplication.run()`: Spring Bootアプリケーションを起動

### 1.2 データ型と変数

RuoYiでは、ドメインオブジェクト（Entity）でデータ型を定義しています。

**実装例:**
```java
// ファイル: ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java:22-104
public class SysUser extends BaseEntity
{
    private static final long serialVersionUID = 1L;

    /** 用户ID */
    private Long userId;

    /** 部门ID */
    private Long deptId;

    /** 登录名称 */
    private String loginName;

    /** 用户名称 */
    private String userName;

    /** 用户邮箱 */
    private String email;

    /** 手机号码 */
    private String phonenumber;

    /** 账号状态（0正常 1停用） */
    private String status;
}
```

**主要なデータ型:**
| 型 | 説明 | 使用例 |
|---|---|---|
| `Long` | 数値型（ID等） | `userId`, `deptId` |
| `String` | 文字列型 | `loginName`, `email` |
| `Date` | 日付型 | `loginDate`, `createTime` |
| `List<T>` | リスト型 | `List<SysRole> roles` |

### 1.3 制御構造

条件分岐やループの典型的な使用例です。

**条件分岐の例:**
```java
// ファイル: ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java:133-152
if (!userService.checkLoginNameUnique(user))
{
    return error("新增用户'" + user.getLoginName() + "'失败，登录账号已存在");
}
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{
    return error("新增用户'" + user.getLoginName() + "'失败，手机号码已存在");
}
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
{
    return error("新增用户'" + user.getLoginName() + "'失败，邮箱账号已存在");
}
```

**ループの例:**
```java
// ファイル: ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java:341-353
for (Long roleId : roleIds)
{
    SysUserRole ur = new SysUserRole();
    ur.setUserId(userId);
    ur.setRoleId(roleId);
    list.add(ur);
}
```

### 1.4 関数/メソッド定義

RuoYiではサービス層でビジネスロジックを実装します。

**メソッド定義の例:**
```java
// ファイル: ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java:21-22
/**
 * 根据条件分页查询用户列表
 *
 * @param user 用户信息
 * @return 用户信息集合信息
 */
public List<SysUser> selectUserList(SysUser user);
```

**アノテーション付きメソッド:**
```java
// ファイル: ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java:80-85
@Override
@DataScope(deptAlias = "d", userAlias = "u")
public List<SysUser> selectUserList(SysUser user)
{
    return userMapper.selectUserList(user);
}
```

### 1.5 モジュール/インポート

Javaのパッケージ構造とインポートの仕組みです。

**インポート文の例:**
```java
// ファイル: ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java:1-36
package com.ruoyi.web.controller.system;

import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.system.service.ISysUserService;
```

**インポートの分類:**
- `java.*`: Java標準ライブラリ
- `org.springframework.*`: Spring Framework
- `org.apache.shiro.*`: Apache Shiro（セキュリティ）
- `com.ruoyi.*`: プロジェクト内部クラス

---

## 2. プロジェクト固有の概念

> このセクションでは、RuoYi特有の概念を解説します。

### 2.1 フレームワーク固有の概念

#### Spring Boot アノテーション

| アノテーション | 説明 | 使用場所 |
|---|---|---|
| `@Controller` | MVCコントローラー | Controllerクラス |
| `@Service` | サービス層コンポーネント | Serviceクラス |
| `@Autowired` | 依存性注入 | フィールド/コンストラクタ |
| `@GetMapping` | HTTP GETマッピング | Controllerメソッド |
| `@PostMapping` | HTTP POSTマッピング | Controllerメソッド |
| `@ResponseBody` | JSON応答 | Controllerメソッド |

#### Apache Shiro アノテーション

```java
// ファイル: ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java:64-69
@RequiresPermissions("system:user:view")
@GetMapping()
public String user()
{
    return prefix + "/user";
}
```

**権限フォーマット:** `モジュール:エンティティ:操作`
- `system:user:view`: システムモジュールのユーザー参照権限
- `system:user:add`: ユーザー追加権限
- `system:user:edit`: ユーザー編集権限

### 2.2 プロジェクト独自のパターン

#### カスタムアノテーション

**@Log - 操作ログ記録:**
```java
// ファイル: ruoyi-common/src/main/java/com/ruoyi/common/annotation/Log.java:19-50
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log
{
    /** 模块 */
    public String title() default "";

    /** 功能 */
    public BusinessType businessType() default BusinessType.OTHER;

    /** 是否保存请求的参数 */
    public boolean isSaveRequestData() default true;
}
```

**使用例:**
```java
// ファイル: ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java:128-130
@Log(title = "用户管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysUser user)
```

**@DataScope - データ権限スコープ:**
```java
// ファイル: ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java:81
@DataScope(deptAlias = "d", userAlias = "u")
```

#### BaseController パターン

すべてのControllerは`BaseController`を継承し、共通機能を利用します。

```java
// ファイル: ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java:33-229
public class BaseController
{
    // ページング開始
    protected void startPage() { ... }

    // テーブルデータ取得
    protected TableDataInfo getDataTable(List<?> list) { ... }

    // 成功/失敗レスポンス
    public AjaxResult success() { ... }
    public AjaxResult error(String message) { ... }

    // ログインユーザー取得
    public SysUser getSysUser() { ... }
}
```

---

## 3. 命名規則

> このセクションでは、プロジェクト全体で使用される命名規則を解説します。

### 3.1 ファイル・ディレクトリ命名

| パターン | 意味 | 例 |
|---------|------|-----|
| `ruoyi-*` | モジュール名 | `ruoyi-admin`, `ruoyi-system` |
| `*Controller.java` | Controllerクラス | `SysUserController.java` |
| `*Service.java` | Serviceインターフェース | `ISysUserService.java` |
| `*ServiceImpl.java` | Service実装クラス | `SysUserServiceImpl.java` |
| `*Mapper.java` | MyBatis Mapperインターフェース | `SysUserMapper.java` |
| `*Mapper.xml` | MyBatis XMLマッピング | `SysUserMapper.xml` |
| `*Config.java` | 設定クラス | `ShiroConfig.java` |

### 3.2 クラス・関数・変数命名

| プレフィックス/サフィックス | 意味 | 例 |
|---------------------------|------|-----|
| `Sys*` | システム管理エンティティ | `SysUser`, `SysRole`, `SysDept` |
| `I*Service` | サービスインターフェース | `ISysUserService` |
| `*ServiceImpl` | サービス実装 | `SysUserServiceImpl` |
| `select*` | 検索メソッド | `selectUserList`, `selectUserById` |
| `insert*` | 登録メソッド | `insertUser` |
| `update*` | 更新メソッド | `updateUser` |
| `delete*` | 削除メソッド | `deleteUserById` |
| `check*` | 検証メソッド | `checkLoginNameUnique` |
| `*Id` | ID項目 | `userId`, `deptId` |
| `*Name` | 名称項目 | `loginName`, `userName` |

### 3.3 プログラム分類一覧

| 分類 | パッケージ | 役割 |
|-----|-----------|------|
| Controller | `com.ruoyi.web.controller` | リクエスト処理 |
| Service | `com.ruoyi.*.service` | ビジネスロジック |
| Mapper | `com.ruoyi.*.mapper` | データアクセス |
| Domain | `com.ruoyi.*.domain` | エンティティ |
| Config | `com.ruoyi.framework.config` | 設定 |
| Util | `com.ruoyi.common.utils` | ユーティリティ |
| Annotation | `com.ruoyi.common.annotation` | カスタムアノテーション |

---

## 4. ディレクトリ構造

> このセクションでは、プロジェクトのディレクトリ構造を解説します。

```
RuoYi-master/
├── ruoyi-admin/           # メインアプリケーションモジュール
│   └── src/main/
│       ├── java/com/ruoyi/
│       │   ├── RuoYiApplication.java    # エントリーポイント
│       │   └── web/
│       │       ├── controller/          # Controllerクラス群
│       │       │   ├── common/          # 共通Controller
│       │       │   ├── demo/            # デモController
│       │       │   ├── monitor/         # 監視Controller
│       │       │   ├── system/          # システム管理Controller
│       │       │   └── tool/            # ツールController
│       │       └── core/config/         # 設定クラス
│       └── resources/
│           ├── application.yml          # アプリケーション設定
│           ├── static/                  # 静的リソース
│           └── templates/               # Thymeleafテンプレート
├── ruoyi-common/          # 共通モジュール
│   └── src/main/java/com/ruoyi/common/
│       ├── annotation/    # カスタムアノテーション
│       ├── config/        # 共通設定
│       ├── constant/      # 定数
│       ├── core/          # コアクラス（BaseController等）
│       ├── enums/         # 列挙型
│       ├── exception/     # カスタム例外
│       └── utils/         # ユーティリティ
├── ruoyi-framework/       # フレームワークモジュール
│   └── src/main/java/com/ruoyi/framework/
│       ├── aspectj/       # AOP処理
│       ├── config/        # フレームワーク設定
│       ├── shiro/         # Shiroセキュリティ
│       └── web/           # Web関連
├── ruoyi-system/          # システム管理モジュール
│   └── src/main/
│       ├── java/com/ruoyi/system/
│       │   ├── domain/    # ドメインオブジェクト
│       │   ├── mapper/    # Mapperインターフェース
│       │   └── service/   # サービス層
│       └── resources/mapper/  # MyBatis XMLマッピング
├── ruoyi-quartz/          # 定時タスクモジュール
├── ruoyi-generator/       # コード生成モジュール
├── sql/                   # SQLスクリプト
└── pom.xml               # Mavenプロジェクト設定
```

### 各ディレクトリの役割

| ディレクトリ | 役割 | 主要ファイル |
|-------------|------|-------------|
| ruoyi-admin | メインアプリケーション、Controller | `RuoYiApplication.java`, Controller群 |
| ruoyi-common | 共通機能、ユーティリティ | アノテーション、ユーティリティ、BaseEntity |
| ruoyi-framework | フレームワーク設定、AOP | ShiroConfig、LogAspect |
| ruoyi-system | システム管理機能 | User/Role/Dept等のCRUD |
| ruoyi-quartz | 定時タスク機能 | SysJob、ScheduleUtils |
| ruoyi-generator | コード生成機能 | GenTable、VelocityUtils |

---

## 5. アーキテクチャ

> このセクションでは、プロジェクトのアーキテクチャパターンを解説します。

### 5.1 全体アーキテクチャ

RuoYiは**レイヤードアーキテクチャ**を採用したMVCパターンのWebアプリケーションです。

```mermaid
graph TD
    A[クライアント] --> B[Controller Layer]
    B --> C[Service Layer]
    C --> D[Mapper Layer]
    D --> E[Database]

    F[Shiro Security] --> B
    G[AOP - Log/DataScope] --> C
```

### 5.2 レイヤー構成

| レイヤー | 責務 | 代表的なファイル |
|---------|------|-----------------|
| Controller | リクエスト処理、レスポンス生成 | `SysUserController.java` |
| Service | ビジネスロジック、トランザクション | `SysUserServiceImpl.java` |
| Mapper | データベースアクセス | `SysUserMapper.java`, `SysUserMapper.xml` |
| Domain | データ構造定義 | `SysUser.java` |
| Config | アプリケーション設定 | `ShiroConfig.java` |

### 5.3 データフロー

1. **リクエスト受信**: ControllerがHTTPリクエストを受信
2. **権限チェック**: Shiroが`@RequiresPermissions`で権限を検証
3. **ビジネス処理**: Serviceがビジネスロジックを実行
4. **データアクセス**: MapperがMyBatisを通じてDB操作
5. **レスポンス生成**: Controllerが結果を返却

```
HTTP Request
    ↓
ShiroFilter (認証・認可)
    ↓
Controller (リクエスト処理)
    ↓
LogAspect (@Log AOP処理)
    ↓
Service (ビジネスロジック)
    ↓
DataScopeAspect (@DataScope AOP処理)
    ↓
Mapper (SQLマッピング)
    ↓
Database
```

---

## 6. 主要コンポーネント

> このセクションでは、主要なコンポーネントとその連携を解説します。

### 6.1 エントリーポイント

アプリケーションの起動は`RuoYiApplication`クラスから開始されます。

```java
// ファイル: ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java:12-29
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class RuoYiApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(RuoYiApplication.class, args);
        System.out.println("若依启动成功");
    }
}
```

**ポイント:**
- `@SpringBootApplication`: コンポーネントスキャン、自動設定を有効化
- `exclude = DataSourceAutoConfiguration.class`: カスタムデータソース設定を使用

### 6.2 ビジネスロジック

サービス層でビジネスロジックを実装します。

```java
// ファイル: ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java:218-230
@Override
@Transactional
public int insertUser(SysUser user)
{
    // 新增用户信息
    int rows = userMapper.insertUser(user);
    // 新增用户岗位关联
    insertUserPost(user);
    // 新增用户与角色管理
    insertUserRole(user.getUserId(), user.getRoleIds());
    return rows;
}
```

**特徴:**
- `@Transactional`: トランザクション管理
- 関連テーブルへの一括登録（ユーザー、役割、岗位）

### 6.3 データアクセス

MyBatisを使用したデータアクセス層です。

**Mapperインターフェース:**
```java
// ファイル: ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java:13-22
public interface SysUserMapper
{
    public List<SysUser> selectUserList(SysUser sysUser);
    public SysUser selectUserByLoginName(String userName);
    public int insertUser(SysUser user);
    public int updateUser(SysUser user);
    public int deleteUserById(Long userId);
}
```

**XMLマッピング:**
```xml
<!-- ファイル: ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml:62-89 -->
<select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
    select u.user_id, u.dept_id, u.login_name, u.user_name, ...
    from sys_user u
    left join sys_dept d on u.dept_id = d.dept_id
    where u.del_flag = '0'
    <if test="loginName != null and loginName != ''">
        AND u.login_name like concat('%', #{loginName}, '%')
    </if>
    <!-- 数据范围过滤 -->
    ${params.dataScope}
</select>
```

### 6.4 ユーティリティ/共通機能

**ShiroUtils - セキュリティユーティリティ:**
```java
// 使用例: ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java:148-151
user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
user.setCreateBy(getLoginName());
```

**StringUtils - 文字列ユーティリティ:**
```java
// 使用例: ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java:140
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
```

**主要ユーティリティ一覧:**
| クラス | 役割 |
|-------|------|
| `ShiroUtils` | 認証・セッション操作 |
| `StringUtils` | 文字列操作 |
| `DateUtils` | 日付操作 |
| `ExcelUtil` | Excel入出力 |
| `ServletUtils` | HTTPリクエスト/レスポンス操作 |

---

## 7. よく使われるパターン

> このセクションでは、コード内で頻出するパターンを解説します。

### パターン一覧

| パターン | 説明 | 出現頻度 | 代表的なファイル |
|---------|------|---------|-----------------|
| Controller-Service-Mapper | 3層アーキテクチャ | 高 | 全CRUD機能 |
| AOPログ記録 | `@Log`による操作ログ | 高 | Controller全般 |
| 権限制御 | `@RequiresPermissions` | 高 | Controller全般 |
| データスコープ | `@DataScope`による権限フィルタ | 中 | Service層 |
| ページング | `startPage()` + `getDataTable()` | 高 | リスト表示機能 |

### 各パターンの詳細

#### パターン1: Controller-Service-Mapper パターン

**目的:** レイヤーを分離し、責務を明確化

**実装例（ユーザー一覧取得）:**

```java
// Controller: ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java:71-79
@RequiresPermissions("system:user:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysUser user)
{
    startPage();
    List<SysUser> list = userService.selectUserList(user);
    return getDataTable(list);
}
```

```java
// Service: ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java:80-85
@Override
@DataScope(deptAlias = "d", userAlias = "u")
public List<SysUser> selectUserList(SysUser user)
{
    return userMapper.selectUserList(user);
}
```

```java
// Mapper: ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java:21
public List<SysUser> selectUserList(SysUser sysUser);
```

**解説:** リクエスト処理(Controller) → ビジネスロジック(Service) → データアクセス(Mapper) の流れで処理

#### パターン2: AOPログ記録パターン

**目的:** 操作ログを自動記録

**実装例:**
```java
// ファイル: ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java:128-153
@RequiresPermissions("system:user:add")
@Log(title = "用户管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysUser user)
{
    // ユーザー追加処理
}
```

**AOP処理:**
```java
// ファイル: ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java:67-71
@AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult)
{
    handleLog(joinPoint, controllerLog, null, jsonResult);
}
```

**解説:** `@Log`アノテーションを付与したメソッドは、自動的に操作ログがDBに記録される

#### パターン3: 権限制御パターン

**目的:** ロールベースのアクセス制御

**実装例:**
```java
// ファイル: ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java:64-69
@RequiresPermissions("system:user:view")
@GetMapping()
public String user()
{
    return prefix + "/user";
}
```

**Shiro認可処理:**
```java
// ファイル: ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/realm/UserRealm.java:56-81
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0)
{
    SysUser user = ShiroUtils.getSysUser();
    if (user.isAdmin())
    {
        info.addStringPermission("*:*:*");  // 管理者は全権限
    }
    else
    {
        menus = menuService.selectPermsByUserId(user.getUserId());
        info.setStringPermissions(menus);
    }
    return info;
}
```

---

## 8. 業務フロー追跡の実践例

> このセクションでは、実際の業務フローをコードで追跡する方法を解説します。

### 8.1 フロー追跡の基本手順

1. エントリーポイントを特定（URLマッピングから）
2. 処理の流れを追跡（呼び出し関係を追う）
3. データの変換を確認
4. 最終的な出力を確認

### 8.2 フロー追跡の実例

#### 例1: ユーザー追加フロー

**概要:** 新規ユーザーを登録する処理の追跡

**処理フロー:**
```
POST /system/user/add → SysUserController.addSave() → ISysUserService.insertUser() → SysUserMapper.insertUser() → DB INSERT
```

**詳細な追跡:**

1. **リクエスト受信** (`ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java:127-153`)
   ```java
   @RequiresPermissions("system:user:add")
   @Log(title = "用户管理", businessType = BusinessType.INSERT)
   @PostMapping("/add")
   @ResponseBody
   public AjaxResult addSave(@Validated SysUser user)
   {
       // 入力検証
       if (!userService.checkLoginNameUnique(user))
       {
           return error("新增用户'" + user.getLoginName() + "'失败，登录账号已存在");
       }
       // パスワード暗号化
       user.setSalt(ShiroUtils.randomSalt());
       user.setPassword(passwordService.encryptPassword(...));
       // 登録実行
       return toAjax(userService.insertUser(user));
   }
   ```

2. **サービス処理** (`ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java:218-230`)
   ```java
   @Override
   @Transactional
   public int insertUser(SysUser user)
   {
       int rows = userMapper.insertUser(user);  // ユーザー登録
       insertUserPost(user);                     // 岗位関連登録
       insertUserRole(user.getUserId(), user.getRoleIds());  // 役割関連登録
       return rows;
   }
   ```

3. **データベース操作** (`ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml:208-244`)
   ```xml
   <insert id="insertUser" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId">
       insert into sys_user(
           <if test="loginName != null and loginName != ''">login_name,</if>
           <if test="userName != null and userName != ''">user_name,</if>
           ...
           create_time
       )values(
           <if test="loginName != null and loginName != ''">#{loginName},</if>
           ...
           sysdate()
       )
   </insert>
   ```

### 8.3 フロー追跡チェックリスト

- [ ] エントリーポイントを特定したか（`@*Mapping`アノテーション）
- [ ] 呼び出し関係を把握したか（Controller → Service → Mapper）
- [ ] データの変換ポイントを確認したか（パスワード暗号化等）
- [ ] エラーハンドリングを確認したか（`try-catch`、バリデーション）
- [ ] 最終的な出力を確認したか（`AjaxResult`、`TableDataInfo`）

---

## 9. 設計書の参照順序

> このセクションでは、プロジェクト理解のための設計書参照順序を案内します。

### 9.1 目的別ロードマップ

#### 全体像を把握したい場合
1. `README.md` - プロジェクト概要
2. `pom.xml` - モジュール構成
3. `application.yml` - アプリケーション設定

#### 特定機能を理解したい場合
1. 対象機能のController（URLマッピングから特定）
2. 対応するService（ビジネスロジック確認）
3. Mapper XML（SQL確認）
4. Domain（データ構造確認）

#### 改修作業を行う場合
1. 既存の類似機能のController/Service
2. 命名規則の確認
3. テンプレート（Thymeleaf）の確認
4. SQLマッピングファイル

### 9.2 ドキュメント一覧

| ドキュメント | 概要 | 参照タイミング |
|-------------|------|---------------|
| `README.md` | プロジェクト概要、機能一覧 | 最初に参照 |
| `pom.xml` | Maven設定、依存関係 | 技術スタック確認時 |
| `application.yml` | アプリケーション設定 | 設定変更時 |
| `sql/ry_*.sql` | データベーススキーマ | テーブル構造確認時 |

---

## 10. トラブルシューティング

> このセクションでは、コードリーディング時によくある問題と解決法を解説します。

### よくある疑問と回答

#### Q: どのControllerがどのURLを処理しているか分からない
A: `@RequestMapping`と`@*Mapping`アノテーションを確認します。
```java
@Controller
@RequestMapping("/system/user")  // 基本パス
public class SysUserController
{
    @GetMapping()       // GET /system/user
    @PostMapping("/list")  // POST /system/user/list
}
```

#### Q: Service層のメソッドがどこから呼ばれているか分からない
A: インターフェース名（`ISysUserService`）でプロジェクト内を検索します。
Controllerで`@Autowired`されている箇所を確認します。

#### Q: SQLがどこに書かれているか分からない
A: Mapperインターフェースのメソッド名で、対応する`*Mapper.xml`を検索します。
- `src/main/resources/mapper/**/*Mapper.xml`

#### Q: アノテーションの動作が分からない
A: カスタムアノテーションは`com.ruoyi.common.annotation`パッケージを確認。
対応するAspectは`com.ruoyi.framework.aspectj`パッケージにあります。

### デバッグのヒント

1. **ログレベルの設定:**
   ```yaml
   # application.yml
   logging:
     level:
       com.ruoyi: debug
   ```

2. **SQLログの有効化:**
   MyBatisのログ出力を有効化することで、実行されるSQLを確認できます。

3. **Shiro権限の確認:**
   ログインユーザーの権限一覧は`sys_menu`テーブルと`sys_role_menu`テーブルで確認できます。

---

## 付録

### A. 用語集

| 用語 | 説明 |
|-----|------|
| RuoYi（若依） | 本プロジェクトの名称 |
| Shiro | Apache Shiro、Javaセキュリティフレームワーク |
| MyBatis | JavaのORマッピングフレームワーク |
| Thymeleaf | サーバーサイドJavaテンプレートエンジン |
| AOP | Aspect Oriented Programming（アスペクト指向プログラミング） |
| Mapper | MyBatisのデータアクセスインターフェース |
| Domain | ドメインオブジェクト（Entity） |
| DataScope | データ権限スコープ（部門による参照制限） |

### B. ファイル一覧

| ファイル/ディレクトリ | 説明 | 主な内容 |
|---------------------|------|---------|
| `RuoYiApplication.java` | エントリーポイント | Spring Boot起動 |
| `BaseController.java` | Controller基底クラス | 共通メソッド |
| `SysUser.java` | ユーザーエンティティ | ユーザー情報 |
| `ShiroConfig.java` | Shiro設定 | セキュリティ設定 |
| `LogAspect.java` | ログAOP | 操作ログ記録 |
| `application.yml` | アプリケーション設定 | DB接続、Shiro設定等 |

### C. 参考資料

- [Spring Boot 公式ドキュメント](https://docs.spring.io/spring-boot/docs/current/reference/html/)
- [Apache Shiro 公式ドキュメント](https://shiro.apache.org/documentation.html)
- [MyBatis 公式ドキュメント](https://mybatis.org/mybatis-3/)
- [RuoYi 公式サイト](http://www.ruoyi.vip)
- [RuoYi ドキュメント](http://doc.ruoyi.vip)
