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?

【Gradle × MyBatis Generator】MBGのカスタムPluginをプロダクションコードから切り離す

0
Posted at

これはなに

  • Gradleプロジェクトにおいて、MyBatis Generator用のファイルをプロダクションコードから切り離して管理したい
  • GradleのSource Setを定義することで解決します

MyBatis Generator(MBG)ではPluginを実装することで、生成されるModelやClientなどを加工することができます。

これを利用して、例えば以下のようにPluginを実装し、MBGの設定ファイルから読み込むことで、Lombokのアノテーションを付与できます。

MyPlugin.java
package plugin;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.TopLevelClass;

import java.util.List;

public class MyPlugin extends PluginAdapter {
    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }

    @Override
    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        topLevelClass.addImportedType("lombok.Builder");
        topLevelClass.addImportedType("lombok.ToString");
        topLevelClass.addImportedType("lombok.EqualsAndHashCode");
        topLevelClass.addAnnotation("@Builder");
        topLevelClass.addAnnotation("@ToString");
        topLevelClass.addAnnotation("@EqualsAndHashCode");

        return true;
    }
}
generatorConfig.xml
<generatorConfiguration>
    <context id="dsql" targetRuntime="MyBatis3">
        <plugin type="plugin.Plugin" />
        ...
    </context>
</generatorConfiguration>

個人的にLombokの@Builderは便利だと思うので、カスタムPluginを実装してアノテーション付与をしています。

ただ、開発を進める中で、カスタムPluginの配置場所を変えたいと思いました。

プロダクションコードに含めると、いろいろ気になる

何も考えず実装すると、配置場所は次のようになりました。

src/
├─ main/
│   ├─ java/
│   │   └─ ...(本来のプロダクションコードのパッケージ)
│   │       ├─ ...
│   │       └─ mbg/
│   │           └─ MyPlugin.java
│   └─ resources/
│       ├─ ...
│       └─ mbg/
│           └─ generatorConfig.xml
└─ test/
    ├─ java/
    └─ resources/

しかしここで、いろいろ気になってきます。

本来のプロダクションコードから一切使用しないのに同じパッケージにある

MBGの設定ファイルならまだしも、カスタムPluginはプロダクションコードから一切使用しないのに、一緒のパッケージに配置しています。

カスタムPluginをプロダクションコードの一部と捉えるならば、特に問題は無いかもしれません。

ただ、同じパッケージに存在することで、

  • 誤ってプロダクションコードから呼び出してしまう (呼び出してどうこうするものではないが、間違えてimportしてから気付いて戻すなど、開発効率を下げうる)
  • 使わないのに、IDEのサジェストにちらつく
  • 本来のプロダクションコードからは一切使用しないのに一緒に置かれているのが、構成上、気になる

などの問題が生じます。

また、次の問題も生じます。

MBG実行にはプロダクションコードはコンパイル可能な状態でなければならない

DB定義と機能実装を同時に行う場合など、実装最中にMBGを実行したくなった場合、この配置はやや厄介です。

なぜなら、MBG実行のためにはコンパイル済みのカスタムpluginが必要であり、カスタムPluginをコンパイルするためにはsrc/main/java配下全体をコンパイル可能な状態にしなければなりません。

実装中の不完全なコードも、コメントアウトやgit stashなどで一旦退避させてからでないと、実行できません。

サクッと実行したいのに、いちいち退避させるのは面倒だと思います。

MBGのPluginを本来のプロダクションコードから切り離したい

ここからが本題です。

先述の問題が生じる原因は、カスタムPluginが、本来のプロダクションコードと同一パッケージ内に配置されているからです。

そこで、本来のプロダクションコードとは別の場所に配置することで、これら問題の解決を試みます。

Source Setを本来のプロダクションコードとは別にする

Gradleでは、Source Setという単位で、Javaファイルと非Javaファイルの抱き合わせを管理しています。

例えば、基本構成であるsrc/main/javasrc/main/resourcesは、これらを一つのSource Setとして管理されています。これをMain Source Setと呼ぶことにします。

Gradleの設定ファイルよりSource Setを追加することで、Main Source Setとは別に、ファイルを管理することができます。

build.gradle.kts
sourceSets {
	create("xxx")
}

上記のようにSource Setを追加することで、Gradleは以下を行ってくれます。

ちなみに、普段、dependenciesに単にImplementationCompileOnlyと書いて動いているのは、これらがMain Source Setに対応するものと定義されているからです。(プロダクトのmainであるため、先頭にSource Set名を付けないものを当てている)

これを利用し、MBG用のファイルを本来のプロダクションコードとは別で管理するようにしてみます。

MBG用のファイルを再配置していく

まずは、MBG用のSource Setを定義します。

build.gradle.kts
sourceSets {
	create("mbg")
}

続いて、カスタムPluginをsrc/mbg/java配下に再配置します。
ついでに、MBG設定ファイルも移しちゃいましょう。

src/
└─ mbg/
    ├─ java/
    │   └─ plugin/
    │       └─ MyPlugin.java
    └─ resources/
        └─ generatorConfig.xml

ここで、再配置後のカスタムPluginファイルを開くと、IDEに怒られてしまいます。

スクリーンショット 2026-01-30 034154.png

依存関係に、MBGを追加していないからですね。

追加していきます。1

build.gradle.kts
dependencies {
    // ...

	// MyBatis Generator
	add("mbgImplementation", "org.mybatis.generator:mybatis-generator-core:1.4.2")
	add("mbgRuntimeOnly", "org.postgresql:postgresql")
}

mbgというSource Setを定義したので、対応して自動定義されるmbgImplementation, mbgRuntimeOnlyに追加することができます。

build.gradle.kts
// IDEでエラーが出る書き方
dependencies {
    mbgImplementation("org.mybatis.generator:mybatis-generator-core:1.4.2")
    mbgRuntimeOnly("org.postgresql:postgresql")
}

上記のように書くと、IDEでは解決できないため、add(...)で追加します。

実行タスクの修正

最後に、実行タスクを修正します。

※ 以下は Qiita:【MyBatis Generator】GradleでサードパーティPluginやAntタスクを使わず実行 を修正する場合の例。

build.gradle.kts
tasks.register<JavaExec>("mbGenerator") {
	dependsOn(tasks.named("mbgClasses"))
	classpath(sourceSets.getByName("mbg").runtimeClasspath)
	mainClass.set("org.mybatis.generator.api.ShellRunner")
	args(
        "-configfile", "src/mbg/resources/generatorConfig.xml",
        "-overwrite",
        "-verbose"
    )
}

カスタムPluginをコンパイルしてからMBG本体を実行するので、dependsOn(tasks.named("mbgClasses"))が必要です。

また、classpathは、mbgのruntimeClasspathのみの指定でOKです。

これで完成です。
本来のプロダクションコードから、MBG用のファイルを切り離して管理することができました。
ターミナルより、./gradlew mbGeneratorでいつでもMBGを実行することができます。

  1. 多くの場合、追記しただけではIDEエラーは消えないと思います。IDEでGradleプロジェクトを再読み込みさせる必要があります。

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?