IntelliJ IDEAにおけるEasyCodeプラグインの活用方法とテンプレート設定

EasyCodeプラグインの導入と設定

1. EasyCodeプラグインのインストール

IntelliJ IDEAのプラグインマーケットプレースから「EasyCode」を検索し、インストールします。インストール後、IDEの再起動が必要です。

2. データベース接続の設定

IntelliJ IDEAは多様なデータベースにネイティブ接続できます。ここではOracleデータベースを例に説明します。

データベース設定画面で必要情報を入力後、下部の「Test Connection」ボタンをクリックして接続を確認します。接続が成功すると、IDE右側にデータベースパネルが表示されます。

3. コード生成の実行(サンプルテーブル:dtp_test)

コードを生成したいテーブルを選択し、右クリックから「EasyCode」→「Generate Code」を選択します。

表示されたダイアログで、生成するコードのパッケージパスを指定し、必要なコンポーネントにチェックを入れて「OK」をクリックします。

4. 生成されたコードの構造

自動生成されたコードは、指定したパッケージ構造に従って配置されます。一般的なMVCアーキテクチャに基づいたファイルが生成されます。

カスタムテンプレートの設定と生成例

エンティティクラス用テンプレート (entity.java.vm)

##初期変数の定義
#set($entityName = $tableInfo.name)
#set($shortEntityName = $tableInfo.name.substring(3))

$!{define.vm}
##コールバック設定
$!callback.setFileName($tool.append($!{entityName}, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/persistence/entity"))
package com.example.demo.persistence.entity;

##自動インポート(グローバル変数)
$!{autoImport.vm}

import io.swagger.annotations.ApiModelProperty;

/**
 * ${tableInfo.comment} エンティティ
 *
 * @author $!author
 * @since $!time.currTime()
 */
public class $!{entityName} {
    
#foreach($column in $tableInfo.fullColumn)

    #if(${column.comment})/**
     * ${column.comment}
     */#end
     
    @ApiModelProperty(value = "${column.comment}")
    private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
#end

#foreach($column in $tableInfo.fullColumn)
##マクロを使用したgetter/setterメソッドの実装
#getSetMethod($column)
#end

    @Override
    public String toString() {
        return "$!{entityName}{" +
#foreach($column in $tableInfo.fullColumn)
                "$!{column.name}='" + $!{column.name} + '\'' +
#end
                "}";
    }
}

リクエストDTO用テンプレート (request.java.vm)

##初期変数の定義
#set($entityName = $tableInfo.name)
#set($shortEntityName = $tableInfo.name.substring(3))
$!{define.vm}
##コールバック設定
$!callback.setFileName($tool.append($!{shortEntityName}, "Request.java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/dto/request"))

package com.example.demo.dto.request;

##自動インポート(グローバル変数)
$!{autoImport.vm}

import io.swagger.annotations.ApiModelProperty;

/**
 * ${tableInfo.comment} リクエストDTO
 *
 * @author $!author
 * @since $!time.currTime()
 */
 
public class $!{shortEntityName}Request {
 
#foreach($column in $tableInfo.pkColumn)

    #if(${column.comment})/**
     * ${column.comment}
     */#end
     
    @ApiModelProperty(value = "${column.comment}")
    private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
#end

#foreach($column in $tableInfo.pkColumn)
##マクロを使用したgetter/setterメソッドの実装
#getSetMethod($column)
#end
}

レスポンスDTO用テンプレート (response.java.vm)

##初期変数の定義
#set($entityName = $tableInfo.name)
#set($shortEntityName = $tableInfo.name.substring(3))
##コールバック設定
$!callback.setFileName($tool.append($!{shortEntityName}, "Response.java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/dto/response"))

package com.example.demo.dto.response;

##自動インポート(グローバル変数)
$!{autoImport.vm}
import com.example.demo.persistence.entity.$!{entityName};

/**
 * ${tableInfo.comment} レスポンスDTO
 *
 * @author $!author
 * @since $!time.currTime()
 */
 
public class $!{shortEntityName}Response extends $!{entityName} {
 
}

APIコントローラ用テンプレート (controller.java.vm)

##初期変数の定義
#set($entityName = $tableInfo.name)
#set($shortEntityName = $tableInfo.name.substring(3))
#set($lowerEntityName = $shortEntityName.toLowerCase())
##コールバック設定
$!callback.setFileName($tool.append($!{shortEntityName}, "Controller.java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/web/controller"))

package com.example.demo.web.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.example.demo.dto.request.$!{shortEntityName}Request;
import com.example.demo.dto.response.$!{shortEntityName}Response;
import com.example.demo.service.$!{shortEntityName}Service;
import com.example.demo.common.ApiResult;
import com.example.demo.common.ApiStatus;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
 * ${tableInfo.comment} コントローラー
 *
 * @author $!author
 * @since $!time.currTime()
 */
@RestController
@RequestMapping("/api/v1/$!{lowerEntityName}")
@Api(tags = "${tableInfo.comment} API")
public class $!{shortEntityName}Controller {
    
    @Autowired
    private $!{shortEntityName}Service $!{lowerEntityName}Service;

    @ApiOperation(value = "${tableInfo.comment}一覧取得")
    @GetMapping
    public ApiResult<List<$!{shortEntityName}Response>> getAll() {
        return ApiResult.success($!{lowerEntityName}Service.findAll());
    }

    @ApiOperation(value = "${tableInfo.comment}ページング取得")
    @GetMapping("/page")
    public ApiResult<Page<$!{shortEntityName}Response>> getPage(Pageable pageable) {
        return ApiResult.success($!{lowerEntityName}Service.findAll(pageable));
    }

    @ApiOperation(value = "${tableInfo.comment}詳細取得")
    @GetMapping("/{id}")
    public ApiResult<$!{shortEntityName}Response> getById(@PathVariable Long id) {
        return ApiResult.success($!{lowerEntityName}Service.findById(id));
    }

    @ApiOperation(value = "${tableInfo.comment}新規作成")
    @PostMapping
    public ApiResult<$!{shortEntityName}Response> create(@Valid @RequestBody $!{shortEntityName}Request request) {
        return ApiResult.success($!{lowerEntityName}Service.create(request));
    }

    @ApiOperation(value = "${tableInfo.comment}更新")
    @PutMapping("/{id}")
    public ApiResult<$!{shortEntityName}Response> update(
            @PathVariable Long id, 
            @Valid @RequestBody $!{shortEntityName}Request request) {
        return ApiResult.success($!{lowerEntityName}Service.update(id, request));
    }

    @ApiOperation(value = "${tableInfo.comment}削除")
    @DeleteMapping("/{id}")
    public ApiResult<Void> delete(@PathVariable Long id) {
        $!{lowerEntityName}Service.delete(id);
        return ApiResult.success();
    }
}

サービス層用テンプレート (service.java.vm)

##初期変数の定義
#set($entityName = $tableInfo.name)
#set($shortEntityName = $tableInfo.name.substring(3))

##コールバック設定
$!callback.setFileName($tool.append($!{shortEntityName}, "Service.java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/service"))

package com.example.demo.service;

import com.example.demo.dto.request.$!{shortEntityName}Request;
import com.example.demo.dto.response.$!{shortEntityName}Response;
import com.example.demo.persistence.entity.$!{entityName};
import com.example.demo.repository.$!{shortEntityName}Repository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * $!{tableInfo.comment} サービス
 *
 * @author $!author
 * @since $!time.currTime()
 */
@Service
@Transactional
public class $!{shortEntityName}Service {

    @Autowired
    private $!{shortEntityName}Repository $!{shortEntityName.toLowerCase()}Repository;

    /**
     * 全件取得
     *
     * @return 全件リスト
     */
    @Transactional(readOnly = true)
    public List<$!{shortEntityName}Response> findAll() {
        return $!{shortEntityName.toLowerCase()}Repository.findAll().stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
    }

    /**
     * ページング取得
     *
     * @param pageable ページング情報
     * @return ページング結果
     */
    @Transactional(readOnly = true)
    public Page<$!{shortEntityName}Response> findAll(Pageable pageable) {
        return $!{shortEntityName.toLowerCase()}Repository.findAll(pageable)
                .map(this::convertToResponse);
    }

    /**
     * ID検索
     *
     * @param id ID
     * @return 検索結果
     */
    @Transactional(readOnly = true)
    public $!{shortEntityName}Response findById(Long id) {
        return $!{shortEntityName.toLowerCase()}Repository.findById(id)
                .map(this::convertToResponse)
                .orElseThrow(() -> new RuntimeException("Entity not found"));
    }

    /**
     * 新規作成
     *
     * @param request 作成リクエスト
     * @return 作成結果
     */
    public $!{shortEntityName}Response create($!{shortEntityName}Request request) {
        $!{entityName} entity = convertToEntity(request);
        entity = $!{shortEntityName.toLowerCase()}Repository.save(entity);
        return convertToResponse(entity);
    }

    /**
     * 更新
     *
     * @param id ID
     * @param request 更新リクエスト
     * @return 更新結果
     */
    public $!{shortEntityName}Response update(Long id, $!{shortEntityName}Request request) {
        return $!{shortEntityName.toLowerCase()}Repository.findById(id)
                .map(entity -> {
                    updateEntity(entity, request);
                    return convertToResponse($!{shortEntityName.toLowerCase()}Repository.save(entity));
                })
                .orElseThrow(() -> new RuntimeException("Entity not found"));
    }

    /**
     * 削除
     *
     * @param id ID
     */
    public void delete(Long id) {
        $!{shortEntityName.toLowerCase()}Repository.deleteById(id);
    }

    /**
     * エンティティをレスポンスに変換
     *
     * @param entity エンティティ
     * @return レスポンス
     */
    private $!{shortEntityName}Response convertToResponse($!{entityName} entity) {
        $!{shortEntityName}Response response = new $!{shortEntityName}Response();
        // マッピングロジック
        return response;
    }

    /**
     * リクエストをエンティティに変換
     *
     * @param request リクエスト
     * @return エンティティ
     */
    private $!{entityName} convertToEntity($!{shortEntityName}Request request) {
        $!{entityName} entity = new $!{entityName}();
        // マッピングロジック
        return entity;
    }

    /**
     * エンティティを更新
     *
     * @param entity エンティティ
     * @param request リクエスト
     */
    private void updateEntity($!{entityName} entity, $!{shortEntityName}Request request) {
        // 更新ロジック
    }
}

リポジトリ層用テンプレート (repository.java.vm)

##初期変数の定義
#set($entityName = $tableInfo.name)
#set($shortEntityName = $tableInfo.name.substring(3))
#set($lowerEntityName = $shortEntityName.toLowerCase())
#set($tableName = $entityName.replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase())
##コールバック設定
$!callback.setFileName($tool.append($!{shortEntityName}, "Repository.java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/repository"))

package com.example.demo.repository;

import com.example.demo.persistence.entity.$!{entityName};
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * ${tableInfo.comment} リポジトリ
 *
 * @author $!author
 * @since $!time.currTime()
 */
@Repository
public interface $!{shortEntityName}Repository extends JpaRepository<$!{entityName}, Long> {

    /**
     * カスタム検索メソッド
     * 
     * @param keyword 検索キーワード
     * @return 検索結果
     */
    @Query("SELECT e FROM $!{entityName} e WHERE " +
#foreach($column in $tableInfo.fullColumn)
           "e.$!{column.name} LIKE %:keyword%#if($foreach.hasNext) OR #end" +
#end
          )
    List<$!{entityName}> findByKeyword(@Param("keyword") String keyword);

    /**
     * 指定条件による検索
     */
#foreach($pkcolumn in $tableInfo.pkColumn)
    @Query("SELECT e FROM $!{entityName} e WHERE e.$!{pkcolumn.name} = :$!{pkcolumn.name}")
    $!{entityName} findBy$!{pkcolumn.name.substring(0, 1).toUpperCase()}$!{pkcolumn.name.substring(1)}(@Param("$!{pkcolumn.name}") $!{pkcolumn.shortType} $!{pkcolumn.name});
#end
}

生成されたコードのカスタマイズ

EasyCodeで生成されたコードは、プロジェクトの要件に合わせてカスタマイズできます。テンプレートを変更することで、生成されるコードの構造や内容を調整することが可能です。

特に、命名規則、パッケージ構造、アノテーションの追加などは、プロジェクトのコーディング規約に合わせてテンプレートを修正することをお勧めします。

タグ: IntelliJ IDEA EasyCode コード生成 テンプレート MyBatis

7月30日 02:46 投稿