ORマッパーとは、リレーショナルデータベースから取得するデータに型をつけたり、CRUD全部をオブジェクトで実現してくれるツールである。なお、ORマッパーと同じ文脈で出てくるORMは、Object-Relational Mappingの略だ。ORマッパーの略で使われることはあまりない。ないと思う。

解決する課題

静的型付け言語に慣れると、そのアシスト力に驚く。このオブジェクトってどんなプロパティ持ってたっけ、この関数の引数ってどんなだっけ。ぜんぶエディタが教えてくれるようになる。もちろん、静的型付けのメリットはこれだけに留まらない。

ただ、この優れた力は言語に留まり、データベースには及ばない。データベースから取得するデータに型をつける、みたいなことは当然できるが、いつ、どこで型をつければいいのか曖昧だ。なんかプラクティスが欲しい。手軽にやってくれるツールがあればなお良い。

ORマッパーはそんな感じで生まれた。

何ができるか

ORマッパーでできることは以下の通り。

できること 説明
エンティティマッピング データベースのテーブルや行をプログラムのクラスやオブジェクトとしてマッピングする。
CRUD操作 Create(作成)、Read(読み込み)、Update(更新)、Delete(削除)などの基本的なデータ操作を提供。
リレーションのサポート テーブル間のリレーション(1対多、多対多など)をオブジェクトとして表現し、リレーショナル操作を抽象化。
トランザクション管理 複数のデータベース操作を1つの処理単位として管理し、一貫性を保つためのトランザクション操作を提供。
クエリビルダー SQLを直接書かずに、プログラム上で動的にクエリを生成する機能。複雑なクエリもビルダーで作成可能。
マイグレーション データベーススキーマの変更を簡単に管理し、バージョン管理を行うツールを提供。
バリデーション データがデータベースに保存される前に、エンティティのプロパティが有効かどうかのチェックを行う。
キャッシュ管理 データベースからの取得結果をキャッシュし、パフォーマンスを向上させる機能を提供。
Eager/Lazyローディング リレーションされたデータをすぐにロードする(Eager)か、必要になったときにロードする(Lazy)かを選択できる。
複数のDBMSサポート 1つのORMで複数のデータベース管理システム(DBMS)に対応し、コードをほぼ変更せずにDBを切り替え可能。
型安全性 特にTypeScriptなどでは、ORMがデータベースのスキーマに基づいて型を生成し、型安全なコードが書ける。
ソフトデリート データを完全に削除せず、論理削除(削除フラグを立てるなど)で削除扱いにする機能。
パフォーマンス最適化 バッチインサート、最適化されたクエリ生成、キャッシュなどによってデータベース操作のパフォーマンスを向上。
カスタムリポジトリ ORMが提供する既定のリポジトリ機能を拡張し、独自のクエリやメソッドを追加する仕組み。
データベース独立性 異なるデータベースシステム間で互換性を持たせ、コード変更なしで異なるDBMSへ移行できる。
ロールバック トランザクション処理の失敗時に、データベース操作を元の状態に戻す機能。
デコレーターによる定義 TypeScriptやJavaなどではデコレーターを使って、クラスにエンティティやカラムなどを簡潔に定義できる。
イベントフック データベース操作(例えば、保存前や保存後)に特定の処理を差し込むことができる。

SQLクエリで実現することはだいたいやってくれると見てよい。

コードの例

例えば以下のようなSQLクエリは、

sql
SELECT
  *
FROM
  users
WHERE
  age >= 20
  AND status = 'active'
ORDER BY
  created_at DESC
LIMIT
  10;

以下のように書ける。

js
const users = await prisma.user.findMany({
  where: {
    age: { gte: 20 },
    status: "active",
  },
  orderBy: {
    createdAt: "desc",
  },
  take: 10,
});

なお、これはPrisma ORMというTypeScriptのORMである。

TypeScriptで言えば、ORマッパーの一覧で検索すると大体以下のようなラインナップが紹介されている。