Skip to main content

如何在 TanStack Start 中使用 Prisma ORM

5 min

介绍

¥Introduction

Prisma ORM 简化了数据库交互,TanStack Start 为构建现代 React 应用提供了一个强大的框架。它们与 Prisma Postgres 一起,提供无缝的全栈开发体验,具有类型安全的查询和高效的数据管理。

¥Prisma ORM simplifies database interactions, and TanStack Start offers a robust framework for building modern React applications. Together with Prisma Postgres, they provide a seamless full-stack development experience with type-safe queries and efficient data management.

本指南将指导你从头开始在 TanStack Start 项目中将 Prisma ORM 与 Prisma Postgres 数据库集成。

¥This guide will walk you through integrating Prisma ORM with a Prisma Postgres database in a TanStack Start project from scratch.

先决条件

¥Prerequisites

1. 设置你的项目

¥ Set up your project

首先,创建一个新的 TanStack Start 项目。

¥To begin, create a new TanStack Start project.

npm create @tanstack/start@latest
信息
  • 你希望如何命名你的项目?tanstack-start-prisma

    ¥What would you like to name your project? tanstack-start-prisma

  • 你想使用 Tailwind CSS 吗?不

    ¥Would you like to use Tailwind CSS? No

  • 选择工具链:无

    ¥Select Toolchain None

  • 选择部署适配器:Nitro

    ¥Select deployment adapter Nitro

  • 你希望为你的项目添加哪些插件?Prisma

    ¥What add-ons would you like for your project? Prisma

  • 需要示例吗?不

    ¥Would you like any examples? No

  • Prisma:数据库提供程序:Prisma、PostgreSQL

    ¥Prisma: Database Provider Prisma PostgresSQL

这将创建一个名为 tanstack-start-prisma 的新文件夹,并为你创建一个新的 Prisma Postgres 数据库。最终的数据库连接字符串将被打印出来。

¥This will create a new folder called tanstack-start-prisma and create a new Prisma Postgres Database for you. The final database connection string will be printed out.

●  Database Connection

│ Connection String:

│ postgresql://b4889.....

复制此连接字符串,并在 .env.local 中设置 DATABASE_URL 变量:

¥Copy this connection string and set the DATABASE_URL variable in .env.local:

# Database URL for PostgreSQL
DATABASE_URL="postgresql://b4889....."

2. 配置 Prisma

¥ Configure Prisma

2.1.定义 Prisma Schema

¥2.1. Define your Prisma Schema

schema.prisma 中,待办事项模型定义在生成器和数据源代码块下方:

¥In schema.prisma, the model for our todos is defined below the generator and datasource blocks:

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

datasource db {
provider = "postgresql"
}

model Todo {
id Int @id @default(autoincrement())
title String
createdAt DateTime @default(now())
}

这将创建一个 Todo 模型并将其推送到数据库。

¥This creates a Todo model that will be pushed to the database

2.2.配置 Prisma 客户端生成器

¥2.2. Configure the Prisma Client generator

现在,运行以下命令创建数据库表:

¥Now, run the following command to create the database tables:

npm run db:seed -- --name init

2.3.种子数据库

¥2.3. Seed the database

生成项目所需的 Prisma Client;

¥Generate the Prisma Client needed for the project;

npm run db:generate

然后使用 prisma/ 目录中的 seed.ts 文件填充项目:

¥Then seed the project with the seed.ts file in the prisma/ directory:

npm run db:seed

打开 Prisma Studio 检查你的数据:

¥And open Prisma Studio to inspect your data:

npm run db:studio

3. 将 Prisma 集成到 TanStack Start

¥ Integrate Prisma into TanStack Start

3.1 Prisma 客户端

¥3.1 The Prisma Client

TanStack Start 不会在每个文件中创建新的 Prisma Client 实例,而是使用 db.ts 创建一个可全局共享的实例。

¥Instead of creating a new Prisma Client instance in each file, TanStack Start has a db.ts that creates a single instance that can be shared globally

src/db.ts
import { PrismaClient } from './generated/prisma/client.js'

import { PrismaPg } from '@prisma/adapter-pg'

const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
})

declare global {
var __prisma: PrismaClient | undefined
}

export const prisma = globalThis.__prisma || new PrismaClient({ adapter })

if (process.env.NODE_ENV !== 'production') {
globalThis.__prisma = prisma
}

3.2 加载时获取数据

¥3.2 Fetch data on load

首先,导入必要的模块。然后,使用 createServerFn 函数创建一个服务器函数。此函数将使用 .findMany() 方法从数据库中获取数据。

¥First, import the necessary modules. Then, create a server function using the createServerFn function. This function will fetch the data from the database using the .findMany() method

src/routes/index.tsx
import { createFileRoute } from "@tanstack/react-router";
import { createServerFn } from "@tanstack/react-start";
import { prisma } from '../db';

export const Route = createFileRoute("/")({
component: Home,
});

const getTodos = createServerFn({ method: "GET" }).handler(async () => {
return prisma.todo.findMany();
});

function Home() {
return (
<div>
</div>
);
}

TanStack Start 允许函数在 createFileRoute 函数中使用加载器函数在负载下运行。使用以下代码在加载时获取用户及其帖子:

¥TanStack Start allows functions to run on load with loader functions in the createFileRoute function. Fetch the users and their posts on load with this code:

app/routes/index.tsx
import { createFileRoute } from '@tanstack/react-router';
import { createServerFn } from '@tanstack/react-start';
import { prisma } from '../db';

export const Route = createFileRoute("/")({
component: Home,
loader: () => {
return getTodos();
},
});

const getTodos = createServerFn({ method: "GET" }).handler(async () => {
return prisma.todo.findMany();
});

function Home() {
return (
<div>
<h1>Todos</h1>
</div>
);
}

使用 Route.useLoaderData() 将加载器的响应存储在主组件中:

¥Store the response from the loader in the main component using Route.useLoaderData():

app/routes/index.tsx
import { createServerFn } from "@tanstack/react-start";
import { createFileRoute } from "@tanstack/react-router";
import { prisma } from '../db';

export const Route = createFileRoute("/")({
component: Home,
loader: () => {
return getTodos();
},
});

const getTodos = createServerFn({ method: "GET" }).handler(async () => {
return prisma.todo.findMany();
});

function Home() {
const todos = Route.useLoaderData();

return (
<div>
<h1>Todos</h1>
</div>
);
}

3.3 显示待办事项

¥3.3 Display the todos

接下来,你需要更新主页以显示从数据库检索的数据。

¥Next, you'll update the home page to display the data retrieved from your database.

映射 todos 并以列表形式显示:

¥Map over the todos and display them in a list:

app/routes/index.tsx
import { createFileRoute } from '@tanstack/react-router';
import { createServerFn } from '@tanstack/react-start';
import { prisma } from '../db';

export const Route = createFileRoute('/')({
component: App,
loader: () => getTodos(),
});

const getTodos = createServerFn({ method: 'GET' }).handler(async () => {
return prisma.todo.findMany();
});

function App() {
const todos = Route.useLoaderData();

return (
<div>
<ul>
{todos.map(todo => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
</div>
);
}

此设置会将待办事项直接从数据库获取并显示在页面上。

¥This setup will display the todos on your page, fetched directly from your database.

下一步

¥Next steps

你已成功将 Prisma ORM 与 TanStack Start 集成,从而创建了一个无缝的全栈应用。以下是一些关于你接下来可以做什么的建议:

¥You've successfully integrated Prisma ORM with TanStack Start, creating a seamless full-stack application. Here are a few suggestions for what you can do next:

  • 扩展你的 Prisma 模型以处理更复杂的数据关系。

    ¥Expand your Prisma models to handle more complex data relationships.

  • 实现额外的 CRUD 操作以增强应用的功能。

    ¥Implement additional CRUD operations to enhance your application's functionality.

  • 探索 Prisma 和 TanStack 的更多功能,加深你的理解。

    ¥Explore more features of Prisma and TanStack Start to deepen your understanding.

  • 查看 Prisma Postgres,了解如何扩展你的应用。

    ¥Check out Prisma Postgres to see how you can scale your application.

更多信息

¥More info


Stay connected with Prisma

Continue your Prisma journey by connecting with our active community. Stay informed, get involved, and collaborate with other developers:

We genuinely value your involvement and look forward to having you as part of our community!