跳到主要内容

如何在 SolidStart 中使用 Prisma ORM

10 分钟

简介

Prisma ORM 通过类型安全的查询和流畅的开发体验简化了数据库访问。SolidStart 是一个用于使用 SolidJS 构建响应式 Web 应用程序的现代框架,它与 Prisma 和 Postgres 结合使用,可以创建清晰且可扩展的全栈架构。

在本指南中,你将学习如何从头开始将 Prisma ORM 与 Prisma Postgres 数据库集成到 SolidStart 项目中。你可以在 GitHub 上找到本指南的完整示例。

先决条件

1. 设置你的项目

首先创建一个新的 SolidStart 应用程序。在你的终端中运行

npm init solid@latest 

在提示时使用以下选项

信息
  • 项目名称: my-solid-prisma-app
  • 这是 SolidStart 项目吗:
  • 模板: bare
  • 使用 TypeScript:

接下来,进入你的新项目,安装依赖项,然后启动开发服务器

cd my-solid-prisma-app
npm install
npm run dev

开发服务器运行后,在浏览器中打开 http://localhost:3000。你应该会看到 SolidStart 欢迎界面。

通过编辑 app.tsx 文件并将其内容替换为以下代码来清理默认 UI

src/app.tsx
import "./app.css";

export default function App() {
return (
<main>
<h1>SolidStart + Prisma</h1>
</main>
);
}

2. 安装和配置 Prisma

2.1. 安装依赖项

要开始使用 Prisma,你需要安装一些依赖项

npm install prisma tsx --save-dev
npm install @prisma/extension-accelerate @prisma/client

安装后,在你的项目中初始化 Prisma

npx prisma init --db --output ../src/generated/prisma
信息

在设置 Prisma Postgres 数据库时,你需要回答几个问题。选择离你最近的区域并为你的数据库取一个令人难忘的名称,例如“我的 SolidStart 项目”

这将创建

  • 一个包含 schema.prisma 文件的 prisma 目录。
  • 一个 Prisma Postgres 数据库。
  • 一个包含项目根目录下的 DATABASE_URL.env 文件。
  • 一个用于生成 Prisma Client 的 output 目录,路径为 src/generated/prisma

2.2. 定义你的 Prisma Schema

prisma/schema.prisma 文件中,添加以下模型并更改生成器以使用 prisma-client 提供程序

prisma/schema.prisma
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}

model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id])
}

这将创建两个模型:UserPost,它们之间存在一对多的关系。

2.3. 配置 Prisma Client 生成器

现在,运行以下命令来创建数据库表并生成 Prisma Client

npx prisma migrate dev --name init

2.4. 填充数据库

让我们添加一些种子数据,用示例用户和帖子填充数据库。

prisma/ 目录下创建一个名为 seed.ts 的新文件

prisma/seed.ts
import { PrismaClient, Prisma } from "../src/generated/prisma/client.js";

const prisma = new PrismaClient();

const userData: Prisma.UserCreateInput[] = [
{
name: "Alice",
email: "alice@prisma.io",
posts: {
create: [
{
title: "Join the Prisma Discord",
content: "https://pris.ly/discord",
published: true,
},
{
title: "Prisma on YouTube",
content: "https://pris.ly/youtube",
},
],
},
},
{
name: "Bob",
email: "bob@prisma.io",
posts: {
create: [
{
title: "Follow Prisma on Twitter",
content: "https://www.twitter.com/prisma",
published: true,
},
],
},
},
];

export async function main() {
for (const u of userData) {
await prisma.user.create({ data: u });
}
}

main();

现在,通过更新你的 package.json 来告诉 Prisma 如何运行此脚本

package.json
{
"name": "prisma-solid",
"type": "module",
"scripts": {
"dev": "vinxi dev",
"build": "vinxi build",
"start": "vinxi start"
},
"prisma": {
"seed": "tsx prisma/seed.ts"
}
"dependencies": {
"@prisma/client": "^6.5.0",
"@prisma/extension-accelerate": "^1.3.0",
"@solidjs/start": "^1.1.0",
"solid-js": "^1.9.5",
"vinxi": "^0.5.3"
},
"engines": {
"node": ">=22"
},
"devDependencies": {
"@types/node": "^22.13.11",
"prisma": "^6.5.0",
"tsx": "^4.19.3"
}
}

运行种子脚本

npx prisma db seed

并打开 Prisma Studio 检查你的数据

npx prisma studio

3. 将 Prisma 集成到 SolidStart 中

3.1. 创建 Prisma Client

在你的项目根目录下,创建一个新的 lib 文件夹并在其中创建一个 prisma.ts 文件

mkdir -p lib && touch lib/prisma.ts

添加以下代码来创建一个 Prisma Client 实例

lib/prisma.ts
import { PrismaClient } from "../src/generated/prisma/client.js";
import { withAccelerate } from "@prisma/extension-accelerate";

const prisma = new PrismaClient().$extends(withAccelerate());

export default prisma;
警告

我们建议使用连接池(例如 Prisma Accelerate)来高效管理数据库连接。

如果你选择不使用连接池,请避免在长期运行的环境中全局实例化 PrismaClient。相反,请为每个请求创建和处置客户端,以防止耗尽数据库连接。

3.2. 创建 API 路由

现在,让我们使用 API 路由从数据库中获取数据。

src/routes/api/users.ts 创建一个新文件

src/routes/api/users.ts
import prisma from "../../../lib/prisma";

export async function GET() {
const users = await prisma.user.findMany({
include: {
posts: true,
},
});
return new Response(JSON.stringify(users), {
headers: { "Content-Type": "application/json" },
});
}

3.3. 在你的组件中获取数据

在你的 app.tsx 文件中,使用 createResource 从你的新 API 路由获取数据

src/app.tsx
import "./app.css";
import { createResource } from "solid-js";
import { User, Post } from "./generated/prisma/client";

type UserWithPosts = User & {
posts: Post[];
};

const fetchUsers = async () => {
const res = await fetch("http://localhost:3000/api/users");
return res.json();
};

export default function App() {
const [users, { mutate, refetch }] = createResource<UserWithPosts[]>(fetchUsers);

return (
<main>
<h1>SolidStart + Prisma</h1>
</main>
);
}
信息

createResource 是 SolidJS 用于管理异步数据的钩子。它会自动跟踪加载和错误状态。了解更多

3.4. 显示数据

要显示用户及其帖子,请使用 SolidJS 的 <For> 组件

src/app.tsx
import "./app.css";
import { createResource, For } from "solid-js";
import { User, Post } from "./generated/prisma/client";

type UserWithPosts = User & {
posts: Post[];
};

const fetchUsers = async () => {
const res = await fetch("http://localhost:3000/api/users");
return res.json();
};

export default function App() {
const [users, { mutate, refetch }] =
createResource<UserWithPosts[]>(fetchUsers);

return (
<main>
<h1>SolidJS + Prisma</h1>
<For each={users() ?? []}>
{(user) => (
<div>
<h3>{user.name}</h3>
<For each={user.posts}>{(post) => <p>{post.title}</p>}</For>
</div>
)}
</For>
</main>
);
}
信息

<For> 响应式地遍历数组。可以把它看作 React 中的 .map()了解更多

3.5. 添加加载和错误状态

使用 SolidJS 的 <Show> 组件来处理加载和错误情况

src/app.tsx
import "./app.css";
import { createResource, For, Show } from "solid-js";
import { User, Post } from "./generated/prisma/client";

type UserWithPosts = User & {
posts: Post[];
};

const fetchUsers = async () => {
const res = await fetch("http://localhost:3000/api/users");
return res.json();
};

export default function App() {
const [users, { mutate, refetch }] =
createResource<UserWithPosts[]>(fetchUsers);

return (
<main>
<h1>SolidJS + Prisma</h1>
<Show when={!users.loading} fallback={<p>Loading...</p>}>
<Show when={!users.error} fallback={<p>Error loading data</p>}>
<For each={users()}>
{(user) => (
<div>
<h3>{user.name}</h3>
<For each={user.posts}>{(post) => <p>{post.title}</p>}</For>
</div>
)}
</For>
</Show>
</Show>
</main>
);
}
信息

<Show> 有条件地渲染内容。它类似于 if 语句。了解更多

你完成了!你刚刚创建了一个连接到 Prisma Postgres 数据库的 SolidStart 应用程序。

下一步

现在你有一个连接到 Prisma Postgres 数据库的 SolidStart 应用程序,你可以

  • 使用更多模型和关系扩展你的 Prisma Schema
  • 添加创建/更新/删除路由和表单
  • 探索身份验证、验证和乐观更新
  • 使用 Prisma Postgres 启用查询缓存以获得更好的性能

更多信息


与 Prisma 保持联系

通过以下方式与我们联系,继续你的 Prisma 之旅 我们的活跃社区。保持信息畅通,参与其中,并与其他开发者协作

我们真诚地重视你的参与,并期待你成为我们社区的一部分!

© . All rights reserved.