使用 MySQL 的 Docker 映像并将数据存储在本机上,与使用 PostgreSQL 的方法类似。以下是详细步骤和代码示例。

1. 创建本地数据目录

首先,在本机创建一个用于存储 MySQL 数据的目录。例如,创建一个名为 mysqldata 的目录:

mkdir -p ~/mysqldata

2. 启动 MySQL 容器并挂载本地目录

使用以下命令启动 MySQL 容器,并将本地 ~/mysqldata 目录挂载到容器内的 /var/lib/mysql 目录:

docker run --name my-mysql \
  -e MYSQL_ROOT_PASSWORD=mysecretpassword \
  -e MYSQL_DATABASE=mydb \
  -d \
  -p 3306:3306 \
  -v ~/mysqldata:/var/lib/mysql \
  mysql:latest

这将执行以下操作:

  • 使用 mysql 映像创建一个名为 my-mysql 的容器。
  • 设置 MySQL 的 root 密码为 mysecretpassword
  • 创建一个名为 mydb 的默认数据库。
  • 将容器的 3306 端口映射到本机的 3306 端口。
  • 将本机的 ~/mysqldata 目录挂载到容器的 /var/lib/mysql 目录,以便数据可以在本机持久化。

3. 配置 Prisma 连接 MySQL

确保你的 Prisma 配置文件 prisma/schema.prisma 中的数据源设置正确,指向本地运行的 MySQL 实例。

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}
 
generator client {
  provider = "prisma-client-js"
}
 
model User {
  id    Int    @id @default(autoincrement())
  name  String
  email String @unique
  posts Post[]
}
 
model Post {
  id       Int    @id @default(autoincrement())
  title    String
  content  String
  author   User   @relation(fields: [authorId], references: [id])
  authorId Int
}

在项目根目录下创建一个 .env 文件,并添加以下内容来配置数据库连接字符串:

DATABASE_URL="mysql://root:mysecretpassword@localhost:3306/mydb"

4. 迁移数据库

使用 Bun 运行 Prisma 迁移命令来生成数据库并创建表:

bun prisma migrate dev --name init

5. 生成 Prisma 客户端

生成 Prisma 客户端:

bun prisma generate

6. 更新项目结构和代码

确保项目结构如下:

elysia-app/
├── prisma/
│   └── schema.prisma
├── src/
│   ├── index.ts
│   ├── routes/
│   │   ├── users.ts
│   │   ├── posts.ts
│   └── models/
│       ├── user.ts
│       └── post.ts
├── .env
├── package.json
└── tsconfig.json

更新用户路由 src/routes/users.ts

import { Router } from "elysia";
import { PrismaClient } from "@prisma/client";
 
const prisma = new PrismaClient();
 
export const userRouter = new Router()
  .get("/", async (req, res) => {
    const users = await prisma.user.findMany({
      include: { posts: true },
    });
    res.json(users);
  })
  .get("/:id", async (req, res) => {
    const user = await prisma.user.findUnique({
      where: { id: parseInt(req.params.id) },
      include: { posts: true },
    });
    if (user) {
      res.json(user);
    } else {
      res.status(404).send("User not found");
    }
  })
  .post("/", async (req, res) => {
    const newUser = await prisma.user.create({
      data: req.body,
    });
    res.status(201).json(newUser);
  });

更新帖子路由 src/routes/posts.ts

import { Router } from "elysia";
import { PrismaClient } from "@prisma/client";
 
const prisma = new PrismaClient();
 
export const postRouter = new Router()
  .get("/", async (req, res) => {
    const posts = await prisma.post.findMany({
      include: { author: true },
    });
    res.json(posts);
  })
  .get("/:id", async (req, res) => {
    const post = await prisma.post.findUnique({
      where: { id: parseInt(req.params.id) },
      include: { author: true },
    });
    if (post) {
      res.json(post);
    } else {
      res.status(404).send("Post not found");
    }
  })
  .post("/", async (req, res) => {
    const newPost = await prisma.post.create({
      data: req.body,
    });
    res.status(201).json(newPost);
  });

主文件 src/index.ts

import { Elysia } from "elysia";
import { userRouter } from "./routes/users";
import { postRouter } from "./routes/posts";
 
const app = new Elysia()
  .use("/users", userRouter)
  .use("/posts", postRouter);
 
app.listen(3000, () => {
  console.log("Server is running on http://localhost:3000");
});

运行项目

使用以下命令运行项目:

bun run src/index.ts

总结

通过将本地目录挂载到 MySQL Docker 容器中,可以在本机持久化数据。在本示例中,我们展示了如何启动一个 MySQL Docker 容器、配置 Prisma 并使用 Elysia 框架构建一个后端应用。这样,你可以充分利用 Docker 的便利性和 MySQL 的强大功能,在本机进行开发和测试。