Webアプリケーション開発では、ユーザー情報や投稿データなどをデータベースへ保存・取得する処理が欠かせません。
こうした操作は通常、SQL文を記述して行いますが、SQLに慣れていないと書くハードルが高く感じられることがあります。
また、コード量が増えやすく、型安全性の確保も課題となりがちです。
そこで、近年のTypeScript・Next.js開発で広く採用されているのが、SQL文を直接記述することなくデータベースを操作しやすくする「ORM(Object Relational Mapping)」と呼ばれるツールです。
本記事では、その中でも特に人気が高い Prisma について紹介していきたいと思います。
Prismaは、TypeScriptとの相性がよく、コードの補完や型チェックを活かしながらデータベースを扱えるORMです。
Next.jsのApp RouterやServer Componentsとも組み合わせやすいため、「データベース操作に不慣れな方」「Next.jsでDB連携を実装したい方」「型安全に開発を進めたい方」に特におすすめです。
本記事では、その中でも特に人気が高い Prisma について紹介していきたいと思います。
- Prismaの基本
- Next.js環境での導入方法
- 具体的な使用方法 (CRUD処理、マイグレーション管理)
- 近年人気のDrizzle ORMとの比較
など、詳しく解説していきますので、ぜひ参考にしてみてください。
Prismaとは
Prismaの基本
Prismaは、Node.jsおよびTypeScript向けのORM(Object Relational Mapping)です。
ORMとは、データベースのテーブルやレコードを、プログラム上のオブジェクトのように扱えるようにする仕組みのことを言います。
通常、データの取得・登録・更新・削除といった操作はSQL文を書いて行いますが、ORMを使うと、こうした操作をTypeScriptのコードから扱いやすくなります。
SQLに不慣れな場合でも、データベース操作に取り組みやすくなる点がメリットです。
PrismaがTypeScript開発で使いやすい理由
Prismaの特徴の一つは、TypeScriptとの相性のよさです。
型補完が効くため、存在しないカラム名を指定したり、型の合わないデータを渡したりといったミスに、コードを書いている段階で気づきやすくなります。
これにより、実行してから初めてエラーに気づく、といった手戻りを減らしやすくなります。
また、Prismaでは「schema.prisma」という設定ファイルをもとに、データベースの構造やモデル(テーブルの定義)を一元的に管理します。
このスキーマを起点に、データを操作するための「Prisma Client」、データベースの変更履歴を管理する「Prisma Migrate」、データをGUIで確認・編集できる「Prisma Studio」といった機能が用意されており、開発から運用まで一貫して扱いやすいように設計されています。
こうした特徴から、Prismaは多くのNext.jsプロジェクトで採用されています。
Prismaの主な機能・特徴
Prismaには、データベース操作を効率化するための機能が複数用意されています。
| 機能・特徴 | 内容 |
|---|---|
| 型安全なデータベース操作 | TypeScriptの型補完が効き、カラム名の誤りや型の不一致に気づきやすい |
| 直感的なAPI | SQLを直接書かずに、データの取得・登録・更新・削除をコードから扱いやすい |
| スキーマ管理 | schema.prismaという設定ファイルで、データベース構造やモデルを一元管理できる |
| マイグレーション | Prisma Migrateにより、テーブル変更の履歴を管理しながら反映できる |
| 複数データベース対応 | PostgreSQL、MySQL、SQLiteなど複数のデータベースに対応している |
| Prisma Studio | データをブラウザ上のGUIで確認・編集できるツール |
これらの機能により、PrismaはTypeScriptやNext.jsを使ったWebアプリケーション開発で扱いやすいORMとして利用されています。
Prisma ormの初期設定:Next.js環境での導入とスキーマ定義
パッケージのインストールとschema.prismaの基本構造
Prismaのインストールは、以下のコマンドで実行可能です。
「prisma」 は CLI、「@prisma/client 」 はクライアントをインストールできます。
Node.jsのインストールがまだの場合は、そちらを先に済ませてから実行してください。
npm install prisma @prisma/clientインストールが完了したら、続いて初期化コマンドを実行します。
npx prisma initコマンドを実行すると、以下のような構成でディレクトリとファイルが生成されます。
sample-app/
├── prisma/
│ └── schema.prisma
└── .env
schema.prismaは、Prismaの中心となる設定ファイルです。
例えば、以下のような内容が記述されています。
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
name String
email String @unique
}各ブロックの役割は次の通りです。
- generator … Prisma Client生成設定
- datasource … 接続先データベースの設定
- model … データベースのテーブル定義
PostgreSQLやMySQLとシームレスに接続するための環境変数設定
データベースの接続情報は .envファイルに記述するのが基本です。
例えば、以下のように環境変数を設定します。
PostgreSQLの場合:
DATABASE_URL="postgresql://user:password@localhost:5432/sampledb"MySQLの場合:
DATABASE_URL="mysql://user:password@localhost:3306/sampledb"接続情報をコードへ直接書かず、環境変数として.envファイルで管理することにより、開発環境と本番環境を安全に切り替えることができます。
【実践】Next.jsでデータベースを操作するCRUDの具体例
PrismaClientの初期設定とシングルトンパターンによる多重接続防止
PrismaClientはホットリロードの度に新しいインスタンスを生成するため、無駄な接続を増やさないためにシングルトン化することが推奨されています。
import { PrismaClient } from "@prisma/client";
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};
export const prisma =
globalForPrisma.prisma ??
new PrismaClient();
if (process.env.NODE_ENV !== "production") {
globalForPrisma.prisma = prisma;
}これにより、不要な接続増加を防ぐことができます。
Server ActionsやRoute Handlersでのデータ取得・保存コード例
データ操作に関するコードをいくつか紹介します。
データ取得(Read):
const users = await prisma.user.findMany();データ登録(Create):
await prisma.user.create({
data: {
name: "Taro",
email: "taro@example.com",
},
});データ更新(Update):
await prisma.user.update({
where: {
id: 1,
},
data: {
name: "Jiro",
},
});データ削除(Delete):
await prisma.user.delete({
where: {
id: 1,
},
});以下は、Route Handlerで利用する例です。
import { prisma } from "@/lib/prisma";
export async function GET() {
const users = await prisma.user.findMany();
return Response.json(users);
}このように、少ないコード量でCRUDを実装できます。
Prisma dbコマンドの活用:db pushとdb pullによる効率的な開発
プロトタイプ開発を加速させるprisma db pushの使い方
スキーマ変更を即座にデータベースに反映したい場合は、db pushを使用します。
npx prisma db pushコマンドを実行すると、schema.prismaの内容がそのままデータベースへ適用されます。
特徴:
・即座にデータベースに反映
・マイグレーションファイルを生成しない
・個人開発や検証環境向け (破壊的変更の可能性があるため)
例えば以下のように、Userモデルへカラムを追加した後、db pushを実行するだけで反映されます。
model User {
id Int @id @default(autoincrement())
name String
age Int?
}既存のデータベース構造をスキーマへ逆生成するprisma db pullの役割
既存のデータベースからスキーマを生成する場合は、db pullを利用します。
npx prisma db pullコマンドを実行すると、データベースの構造を解析してschema.prismaに反映させます。
既存システムへPrismaを導入する際に便利です。
【運用】prisma migrateを用いた安全なマイグレーション管理
チーム開発で変更履歴をSQLとして残すmigrate devの仕組み
本格的な開発では、マイグレーション管理が重要となります。
開発時のマイグレーションは以下のコマンドで実行します。
npx prisma migrate dev --name <マイグレーション名>実行すると、以下のような構成で SQLファイルが生成されます。
prisma/
└── migrations/
└── [日付]_[マイグレーション名]
└── migration.sql
マイグレーションを行うと、migrationsディレクトリ配下で変更履歴を管理できるだけでなく、ファイルを Git管理することも可能です。
また、構造の再現が容易となるため、特にチーム開発では重要な機能となります。
本番環境のデータベースへ安全に変更を適用するmigrate deployの手順
本番環境でマイグレーションを実行する場合は、以下のコマンドを使用します。
npx prisma migrate deploy上記コマンドではSQLファイルの新規生成は行わず、未適用の既存ファイルのみマイグレーションを実行します。
一般的な使用の流れは、以下の通りです。
- 開発環境でmigrate dev
- Gitへコミット
- 本番環境へデプロイ
- migrate deploy実行
これにより、開発環境と本番環境の差異を防げます。
Prismaとライバル「Drizzle ORM」の比較から考える選定基準
スキーマ定義の記述アプローチと型安全性の思想の違い
近年では、Prismaの他に Drizzle ORMも人気が高くなっています。
両者の特徴的な違いの1つは、スキーマ定義の記述方法にあります。
Prismaのスキーマ定義は、ドメイン特化言語(DSL) で行います。
model User {
id Int @id
name String
}Prismaの型安全性は強力で、スキーマを元に自動で生成されるTypeScriptの型定義ファイルを利用し、クエリを記述する際にTypeScriptのコンパイラが型チェックを行います。
これにより、正確な型推論やエラー検知を可能としています。
一方、Drizzleは TypeScriptで直接スキーマ定義をします。
export const users = pgTable("users", {
id: serial("id").primaryKey(),
name: text("name"),
});Prismaのような生成ステップが必要なく、TypeScriptの型推論を利用するため、リアルタイムで型生成が行われるのが特徴です。
スキーマの反映速度においては、Drizzleの方にやや軍配が上がります。
プロジェクトの規模やパフォーマンス要件に応じた技術選定のポイント
PrismaとDrizzleの全体的な特徴は、それぞれ以下が挙げられます。
Prisma:
・学習コストが低い
・ドキュメントが豊富
・DX重視
Drizzle
・TypeScriptとの一体感が強い
・軽量
・SQLに近い設計
Prismaは DSLの導入により、SQL操作に慣れていないユーザーでも記述しやすく、簡潔なコードを可能としています。
Drizzleは反対に、SQLに近い操作を可能とするため、複雑なクエリの調整も行いやすい傾向にあります。
開発環境などに合わせた選定は、以下を基準にすると行いやすいでしょう。
Prismaが向くケース:
・SQL経験者が少ない
・チーム開発などでマイグレーション管理が重要である
・開発効率を重視したい
Drizzleが向くケース:
・SQLを積極的に活用したい
・パフォーマンスやバンドルサイズを重視したい
・ORMの抽象化を最小限にしたい
まとめ
PrismaはTypeScriptとの相性が非常に良く、型安全なデータベース操作を実現できるモダンなORMです。
Web開発における生産性と保守性を大きく向上させるため、これからORMを学ぶ開発者にとって最有力候補の一つと言えるでしょう。