Drizzle ORMのクエリ操作概要

Drizzle ORMは、SQLライクな構文をサポートしているため、SQLの知識を持つ開発者にとって直感的に利用可能です。また、複雑なリレーショナルデータの取得を効率化するためのAPIも提供されています。Drizzle ORMは特にサーバーレス環境でのパフォーマンスを考慮した設計が特徴で、パフォーマンスの高いSQLクエリを自動生成します。

SQLライクなクエリ操作

Drizzle ORMは、SQLに似た構文でデータベース操作を行うため、他のORMのように新たなAPIを学ぶ必要がありません。以下に基本的なクエリ操作の例を示します。

SELECTクエリ

特定の条件でデータを選択する際は、以下のようなSQLに似た記述が可能です。

const result = await db
  .select()
  .from(posts)
  .leftJoin(comments, eq(posts.id, comments.post_id))
  .where(eq(posts.id, 10));

この例では、postsテーブルとcommentsテーブルをJOINし、posts.idが10である投稿のコメントを取得しています。SQLの知識があれば、Drizzle ORMでもすぐに理解しやすい構文となっています。

INSERTクエリ

新しいレコードを挿入する場合も、SQLと同様の直感的な構文で行います。

await db.insert(users).values({ email: 'user@example.com' });

上記はusersテーブルに新しいユーザーのメールアドレスを挿入するクエリです。Drizzle ORMのINSERT文は、SQLの文法に沿った記述でスムーズに追加処理が行えます。

UPDATEとDELETEクエリ

既存のデータを更新・削除する場合も、SQLの構文に近い操作が可能です。

// UPDATE操作
await db.update(users).set({ email: 'new_email@example.com' }).where(eq(users.id, 1));
// DELETE操作
await db.delete(users).where(eq(users.id, 1));

usersテーブルの特定のユーザー情報を更新・削除する際も、シンプルで読みやすい構文で行えるため、コードの保守性も高まります。

クエリAPIを活用したリレーショナルデータの取得

Drizzle ORMには、複雑なリレーショナルデータを簡単に取得できるクエリAPIが提供されています。JOIN構文を使用せずに、リレーションやネスト構造を効率よく処理することが可能です。

const result = await db.query.users.findMany({
  with: { posts: true }
});

上記のように、usersとそれに関連するpostsデータを一度に取得できるため、APIのパフォーマンスが向上します。

高度なクエリ構築のためのテクニック

Drizzle ORMでは、条件やフィルタを個別に設定したり、サブクエリを柔軟に構成することが可能です。以下の例は、複数の条件を組み合わせたクエリ構築を示しています。

動的なフィルタの設定

複数のフィルタ条件を動的に追加し、効率的にデータを検索する方法です。

async function getProductsBy({ name, category, maxPrice }: {
  name?: string;
  category?: string;
  maxPrice?: string;
}) {
  const filters: SQL[] = [];
  
  if (name) filters.push(ilike(products.name, name));
  if (category) filters.push(eq(products.category, category));
  if (maxPrice) filters.push(lte(products.price, maxPrice));
  
  return db.select().from(products).where(and(...filters));
}

このように条件を動的に設定することで、柔軟なクエリを構築できます。条件が増えると自動的にWHERE句に適用されるため、コードの再利用性が高まります。

サブクエリの活用

Drizzle ORMでは、サブクエリを変数として分離し、メインクエリ内で使用することも可能です。

const subquery = db
  .select()
  .from(internalStaff)
  .leftJoin(customUser, eq(internalStaff.userId, customUser.id))
  .as('internal_staff');
const mainQuery = await db
  .select()
  .from(ticket)
  .leftJoin(subquery, eq(subquery.internal_staff.userId, ticket.staffId));

このようなサブクエリは、SQLの高度な機能を必要とする場合に役立ちます。サブクエリを別々に定義することで、読みやすく再利用可能なコードを実現できます。

まとめ

Drizzle ORMのクエリ操作は、SQLに馴染みがある開発者にとって学習コストが少なく、非常に柔軟かつ強力なデータ操作が可能です。基本的なSELECT、INSERT、UPDATE、DELETEだけでなく、クエリAPIを使用することでリレーショナルデータの効率的な取得が可能になります。また、動的フィルタやサブクエリ構築により、複雑なデータ要求にも対応できるため、エンタープライズレベルのアプリケーション開発においても非常に有用です。

参照:

Query data