メインコンテンツまでスキップ

IDEA プラグイン開発の記録

· 約7分

以前からずっと mybatis log plugin というプラグインを使っていて、その中の sql log パラメータ補完という機能がかなり気に入っていました。以前の低いバージョンでは有料化されていなかったようなのですが、高いバージョンから有料になってしまいました。そこで自分で似た機能のプラグインを開発することにし、名前を mybatis log analysis としました。1.0.0 バージョンでは、まず sql log の解析と自動パラメータ補完、sql の整形といったシンプルな機能を完成させます。

なぜこのプラグインを作るのか

MyBatis で業務コードを書いている人なら実感があるはずです。コンソールに出力される SQL は ? プレースホルダー付きのプリペアドステートメントで、パラメータは別の行に単独で出力されます。問題を調査するとき、この SQL をデータベースクライアントに持っていって直接実行しようとすると、パラメータを 1 つずつ手作業で埋め戻さなければなりません——パラメータが多くなると、この作業は面倒なうえに位置を間違えやすいのです。パラメータ補完系のプラグインが解決するのは、まさにこの小さいけれど高頻度な作業です。だから、いつも使っていたあのプラグインが有料化したとき、私の最初の反応は代替品を探すことではなく、この機能自体は別に神秘的なものではないのだから自分で書いてしまおう、ついでに IDEA プラグイン開発という道を一通り体験してみよう、というものでした。

プラグインの機能計画

1.0.0 バージョンでは、まず最も核心的でよく使われる部分を作ります。

  1. sql log の解析と自動パラメータ補完;

  2. sql の整形(フォーマットして出力し、長い SQL を読みやすくする)。

その後、時間に余裕ができたら他の便利機能も開発していく予定です。たとえば xml と java 間のリンクジャンプ、controller、service、entity、mapper、xml のワンクリック生成といった機能です。

現在すでに 1.0.0 バージョンの開発を完了し、IDEA PLUGIN リポジトリに提出済みです。

パラメータ補完の原理

この機能の原理は複雑ではありません。MyBatis はログレベルを DEBUG にすると、1 回のクエリを 2 行に分けて出力します。

==> Preparing: select * from user where id = ? and status = ?
==> Parameters: 1024(Long), 1(Integer)

Preparing 行はプレースホルダー付きのプリペアド SQL で、Parameters 行は順番に並んだパラメータ値、括弧内にはパラメータの Java 型が付記されています。プラグインがやるべきことは、この 2 行をペアリングすることです。

  1. ログテキストから隣接する Preparing 行と Parameters 行を特定する;

  2. カンマでパラメータリストを分割し、括弧内の型に応じて連結方法を決める——文字列や日付型は引用符を付ける必要があり、数値型はそのまま置換する;

  3. 処理後のパラメータを順番に SQL 内の ? へ埋め戻し、そのまま実行できる完全な文を得る;

  4. 最後に SQL フォーマットを一度かけて、整形された結果を出力する。

コアロジックはテキスト解析と文字列置換だけです。むしろ本当に時間がかかったのは、プラグインと IDE の統合部分でした。ツールウィンドウをどう登録するか、コンソール出力をどう監視するか、アクションをどうメニューにぶら下げるか——これらはすべて IntelliJ プラットフォームの API と付き合う必要があります。

開発過程で感じたこと

プラグインを開発していると、シンプルな機能の実装は実に簡単なのですが、少し複雑な機能を実装しようとすると、IDEA が提供する API などのメソッドをかなり深く理解していなければなりません。ところが公式のプラグインドキュメントには、十分に整備された API ドキュメントが見当たりませんでした。あるのは公式が提供するいくつかの demo コードだけです。そうなると、時間をかけて demo コードを読み込んで理解するしかありません。あまり優しくない学習曲線になりそうだと感じました。

この点は普段の業務開発とは大きく異なります。業務フレームワークのドキュメントは通常「API を調べて、サンプルを見て、そのまま使う」という流れですが、IntelliJ プラットフォームでは主に 3 つの方法で手探りすることになります。公式の demo リポジトリをあさる、プラットフォームのソースコードを直接読む、そして他のオープンソースプラグインが類似機能をどう実装しているかを見る、です。どの拡張ポイントを使えばいいか分からないときは、機能が近いオープンソースプラグインを見つけて、その plugin.xml とエントリクラスを照らし合わせるほうが、ドキュメントをめくるより早いことが多いです。

開発済みのプラグインのアドレスを貼っておきます:https://plugins.jetbrains.com/plugin/14958-mybatis-log-analysis

ハマりどころと注意点

  • パラメータ置換を単純なグローバル文字列置換でやってはいけません。パラメータ値自体にカンマや疑問符が含まれる可能性があるため、Parameters 行をカンマで分割して順番に 1 つずつ ? を置換するほうが、一括の正規表現置換よりずっと堅実です。
  • 型情報を活用しましょう。Parameters 行の括弧内の型が引用符を付けるかどうかを決めます。これを無視して組み立てた SQL は、データベースでまず実行できません。
  • JetBrains プラグインマーケットへの提出には人手による審査が必要です。プラグインの説明、アイコン、互換性のある IDE のバージョン範囲を設定にきちんと書いておく必要があり、これらを事前に準備しておけば、やり直しの往復を何回か減らせます。
ヒント

プラグイン開発ドキュメントで足りないときは、IntelliJ Platform SDK ドキュメントとオープンソースプラグインのソースコードを照らし合わせて読むのが、現時点で最も体験の良い学習ルートです。

小まとめ

このプラグイン自体のロジックはとても小さく、その価値は高頻度の手作業を自動化した点にあります。私にとってより大きな収穫は、IDEA プラグインの開発から公開までのプロセスを一通り完走したことでした。機能の実装はほんの一部分にすぎず、プラットフォームの拡張機構を理解し、ソースコードと demo を読んで学ぶスタイルに慣れることこそが、この道における本当のハードルです。今後のバージョンでは、xml と java 間のジャンプや、コードのワンクリック生成といった機能を引き続き追加していきます。

COMMENTS