Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Doma で目指す ORM 最適解

Doma で目指す ORM 最適解

Java向け軽量ORM「Doma」の特徴と、3つのデータアクセススタイル(宣言型・テンプレート・ビルダー)を使い分けることで、開発効率・保守性・信頼性を両立するアプローチを紹介。

Avatar for Toshihiro Nakamura

Toshihiro Nakamura

May 23, 2025
Tweet

More Decks by Toshihiro Nakamura

Other Decks in Programming

Transcript

  1. 自己紹介 • 名前 :中村年宏 • X :nakamura_to • GitHub :nakamura-to

    • サーバサイド Kotlin 向けの ORM も作っています • https://github.com/komapper/komapper 2
  2. Doma とは • アノテーションプロセッサーによりコンパイル時に ソースコードを生成するタイプの ORM • https://github.com/domaframework/doma • 2009年に開発開始

    • その他特長 • 暗黙的な SQL の発行なし • 検索結果のキャッシュなし • 依存ライブラリなし 4 https://deepwiki.com/domaframework/doma より抜粋
  3. Java クラスと DB テーブルのマッピング @Entity class Person { @Id Integer

    id; String name; int age; } CREATE TABLE person ( id INT PRIMARY KEY, name VARCHAR(255) NOT NULL, age INT NOT NULL ); 6 Java のエンティティクラス定義 DB のテーブル定義 • マッピングはアノテーションで行う • 次項以降では次のマッピング定義が存在することを前提とする
  4. 宣言型スタイル @Dao interface PersonDao { @Insert int insert(Person person); @Update

    int update(Person person); @Delete int delete(Person person); } var config = SimpleConfig.builder("jdbc:h2:mem:test").build(); var dao = new PersonDaoImpl(config); var person = new Person(); person.id = 1; person.name = "hoge"; person.age = 30; dao.insert(person); コード例 呼び出し例 insert into Person (id, name, age) values (?, ?, ?) 発行される SQL 7 • アノテーションを注釈されたメソッドが更新系 SQL を自動生成する • 利点:実装不要 • 制約:検索系 SQL の自動生成は非サポート
  5. テンプレートスタイル select * from person where name = ‘test‘ and

    age = 0 ベースとなる SQL (コメントを全て除去したもの) コード例 8 • テンプレートを使って SQL を組み立てる • 利点:あらゆる SQL の組み立てが可能 • 制約:テンプレート間で検索条件を共通化する仕組みはなし -- name と age がどちらも非 null の時 select id, name, age from person where name = ? and age = ? -- name が非 null、age が null の時 select id, name, age from person where name = ? -- name が null、age が非 null の時 select id, name, age from person where age = ? -- name と age がどちらも null の時 select id, name, age from person 生成されるSQL(4パターン)
  6. ビルダースタイル コード例 9 • コンパイル時に生成されるメタモデルクラスを使ってタイプセーフに SQL を組み立てる • 利点:検索条件の共通化が容易 •

    制約:複雑な SQL は Java コードが冗長化しやすい -- name と age がどちらも非 null の時 select id, name, age from person where name = ? and age = ? -- name が非 null、age が null の時 select id, name, age from person where name = ? -- name が null、age が非 null の時 select id, name, age from person where age = ? -- name と age がどちらも null の時 select id, name, age from person 生成されるSQL(4パターン)
  7. 3つのスタイルの特徴まとめ スタイル 自動化 型安全 自由度 適用例 宣言型 ◎ ◎ ×

    追加、更新、削除 の自動化 テンプレート × × ◎ 複雑・長大な SQL の構築 ビルダー ◦ ◎ ◦ 検索条件の共通化 10
  8. スタイル選定のポイント プロジェクト規模/特性 スタイル 特長 注意点 小〜中規模/ プロトタイピング ビルダー中心 開発速度重視。 堅安全性を生かし、早期にミスを検出。

    ビルダーによる無理なSQLの組み立ては 保守性を損ねる。 中〜大規模 3つのスタイルの 使い分け 保守性重視。 適材適所(単純な検索はビルダー、複 雑な検索はテンプレート、更新系は宣 言型)によりコードの見通しが良くなる。 3つのスタイルを覚える必要があり学習コ ストは高い。 大規模/ マイグレーション テンプレート中心 信頼性重視。 発行されるSQLを明示的にすることで、 想定外の不具合混入を防止する。 重複コードが生まれやすく、非効率的と なる怖れあり。 11
  9. ベストプラクティス 12 • スタイルを組み合わせる • 1つのDAOに複数スタイルの定義OK • 状況に応じてスタイルを切り替える • 呼び出し元に影響しないので躊躇不要

    • 宣言型スタイルを活用する • シンプルだが多くの機能をサポート • Multi-row INSERT • INSERT ... ON CONFLICT ... • INSERT ... RETURNING ...