prisma 初步使用

前言

prisma 是 nodejs 一款 ORM框架,也就是所谓的代码 根据 数据库表结构 进行 逆向生成!

生成类型

prisma根据数据库表结构生成的类型在客户端里

表结构如下

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `password` varchar(255) DEFAULT NULL,
  `role` varchar(255) DEFAULT NULL,
  `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `des` varchar(255) DEFAULT NULL,
  `nickname` varchar(255) DEFAULT NULL,
  `avatar` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

600

最终生成的User Ts类型代码如下,

{
      id: number
      email: string
      password: string | null
      role: string | null
      username: string | null
      des: string | null
      nickname: string | null
      avatar: string | null
    }

可以如下导入

import {user as User } from '@prisma/client';

但是这显然,不太符合作为入参,因为可以为空的,本质上都是可选的,
所以prisma又提供了另一种方式,用来更新或者创建对应实体的类型.。
可以看到 自增的 id没有出现这这里、可为空的属性都加了可选项ts标识。

  export type userCreateInput = {
    email: string
    password?: string | null
    role?: string | null
    username?: string | null
    des?: string | null
    nickname?: string | null
    avatar?: string | null
  }

通过如下方式使用

import { Prisma } from '@prisma/client';

const input: Prisma.userCreateInput = {
  // ....
}

Prisma 为每个实体(模型)自动生成了对应的 CreateInput 类型。这些类型用于定义在创建实体时需要提供的字段。例如,如果你有一个 User 模型,Prisma 会生成 Prisma.userCreateInput 类型,针对更新你可以用 Prisma.userUpdateInput

如果这还不能满足你,你可以自行使用 Partial,手动将其改为可选属性项

userUpdateInput 和 userCreateInput 区别

Prisma.UserCreateInputPrisma.UserUpdateInput 是 Prisma 自动生成的两种不同类型的输入对象,它们分别用于创建和更新操作。这两种类型在设计和用途上有明显的区别,以下是一些关键点:

1. Prisma.UserCreateInput

  • 用途:用于创建新记录时的输入数据。
  • 字段
    • 包含所有非自增字段。
    • 不包含自增字段(如 id),因为这些字段由数据库自动生成。
    • 所有字段通常都是可选的,但某些字段可能是必填的,具体取决于模型定义。
  • 示例
    type UserCreateInput = {
      email?: string | null;
      password?: string | null;
      role?: string | null;
      username?: string | null;
      des?: string | null;
      nickname?: string | null;
      avatar?: string | null;
    };
    

2. Prisma.UserUpdateInput

  • 用途:用于更新现有记录时的输入数据。
  • 字段
    • 包含所有非自增字段。
    • 所有字段都是可选的,因为更新操作允许部分字段更新。
    • 不包含自增字段(如 id),因为这些字段用于标识要更新的记录,而不是更新的内容。
  • 示例
    type UserUpdateInput = {
      email?: string | null;
      password?: string | null;
      role?: string | null;
      username?: string | null;
      des?: string | null;
      nickname?: string | null;
      avatar?: string | null;
    };
    

主要区别

  1. 字段可选性

    • Prisma.UserCreateInput:某些字段可能是必填的,具体取决于模型定义。
    • Prisma.UserUpdateInput:所有字段都是可选的,因为更新操作允许部分字段更新。
  2. 自增字段

    • Prisma.UserCreateInput:不包含自增字段(如 id),因为这些字段由数据库自动生成。
    • Prisma.UserUpdateInput:同样不包含自增字段,因为这些字段用于标识要更新的记录,而不是更新的内容。
  3. 用途

    • Prisma.UserCreateInput:用于创建新记录。
    • Prisma.UserUpdateInput:用于更新现有记录。

userWhereUniqueInput

Prisma.UserWhereUniqueInput 是 Prisma 自动生成的一个类型,用于在更新或删除操作中唯一地标识一个记录。它通常包含模型中定义的唯一字段(如 idemail 等),这些字段可以用来唯一地定位数据库中的某一条记录。

用途

Prisma.UserWhereUniqueInput 主要用于以下场景:

  • 更新操作:在更新记录时,需要指定要更新的记录。
  • 删除操作:在删除记录时,需要指定要删除的记录。

示例

假设你的 Prisma 模型定义如下:

model User {
  id       Int      @id @default(autoincrement())
  email    String   @unique
  password String?
  role     String?
  username String?
  des      String?
  nickname String?
  avatar   String?
}

Prisma 会自动生成以下类型:

type UserWhereUniqueInput = {
  id?: number;
  email?: string;
};

使用 Prisma.UserWhereUniqueInput

在更新或删除操作中,你可以使用 Prisma.UserWhereUniqueInput 来指定要操作的记录。

更新用户

import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

app.put('/user/:id', async (req, res) => {
  const userId = parseInt(req.params.id);
  const updateData: Prisma.UserUpdateInput = req.body;

  try {
    const updatedUser = await prisma.user.update({
      where: { id: userId }, // 使用 UserWhereUniqueInput
      data: updateData,
    });
    res.json(updatedUser);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

删除用户

import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

app.delete('/user/:id', async (req, res) => {
  const userId = parseInt(req.params.id);

  try {
    const deletedUser = await prisma.user.delete({
      where: { id: userId }, // 使用 UserWhereUniqueInput
    });
    res.json(deletedUser);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

为什么需要 Prisma.UserWhereUniqueInput

  • 唯一标识记录Prisma.UserWhereUniqueInput 包含模型中定义的唯一字段,这些字段可以用来唯一地定位数据库中的某一条记录。
  • 类型安全:使用 Prisma.UserWhereUniqueInput 可以确保你在更新或删除操作中使用正确的字段来标识记录,从而避免错误。
  • 灵活性:你可以选择使用任何一个唯一字段来标识记录,例如 idemail

总结

Prisma.UserWhereUniqueInput 是一个非常有用的类型,它用于在更新或删除操作中唯一地标识记录。它包含模型中定义的唯一字段,确保你在操作记录时使用正确的字段。通过使用 Prisma.UserWhereUniqueInput,你可以提高代码的类型安全性和灵活性。

userWhereInput

const queryOne = async (user: xxx

这里改用啥类型,理论上,查询条件是任一属性,或多个属性 ?

在 Prisma 中,查询条件通常使用 Prisma.UserWhereInput 类型。这个类型允许你指定一个或多个字段作为查询条件,这些字段可以是模型中的任何字段,包括非唯一字段。

Prisma.UserWhereInput

Prisma.UserWhereInput 是一个非常灵活的类型,它允许你指定一个或多个字段作为查询条件。你可以使用它来构建复杂的查询条件,包括比较操作、逻辑运算符等。

示例

假设你的 Prisma 模型定义如下:

model User {
  id       Int      @id @default(autoincrement())
  email    String   @unique
  password String?
  role     String?
  username String?
  des      String?
  nickname String?
  avatar   String?
}

Prisma 会自动生成以下类型:

type UserWhereInput = {
  AND?: UserWhereInput[] | UserWhereInput;
  OR?: UserWhereInput[];
  NOT?: UserWhereInput[] | UserWhereInput;
  id?: IntFilter | number;
  email?: StringFilter | string;
  password?: StringNullableFilter | string | null;
  role?: StringNullableFilter | string | null;
  username?: StringNullableFilter | string | null;
  des?: StringNullableFilter | string | null;
  nickname?: StringNullableFilter | string | null;
  avatar?: StringNullableFilter | string | null;
};

使用 Prisma.UserWhereInput

在查询操作中,你可以使用 Prisma.UserWhereInput 来指定查询条件。以下是一些示例:

查询单个用户

import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

const queryOne = async (user: Prisma.UserWhereInput) => {
  try {
    const foundUser = await prisma.user.findFirst({
      where: user,
    });
    return foundUser;
  } catch (error) {
    console.error(error);
    throw error;
  }
};

// 示例调用
queryOne({ email: 'example@example.com' }).then((user) => {
  console.log(user);
});

查询多个用户

const queryMany = async (user: Prisma.UserWhereInput) => {
  try {
    const foundUsers = await prisma.user.findMany({
      where: user,
    });
    return foundUsers;
  } catch (error) {
    console.error(error);
    throw error;
  }
};

// 示例调用
queryMany({ role: 'admin' }).then((users) => {
  console.log(users);
});

复杂查询条件

Prisma.UserWhereInput 支持复杂的查询条件,包括逻辑运算符(ANDORNOT)和比较操作。

示例:复杂查询条件

const complexQuery = async () => {
  try {
    const users = await prisma.user.findMany({
      where: {
        AND: [
          { role: 'admin' },
          { OR: [{ email: 'example@example.com' }, { username: 'exampleUser' }] }
        ]
      }
    });
    return users;
  } catch (error) {
    console.error(error);
    throw error;
  }
};

// 示例调用
complexQuery().then((users) => {
  console.log(users);
});

总结

  • Prisma.UserWhereInput:用于指定查询条件,支持一个或多个字段,以及复杂的逻辑运算符。
  • 灵活性:你可以使用任何字段作为查询条件,包括非唯一字段。
  • 类型安全:Prisma 自动生成的类型确保了查询条件的类型安全。

因此,如果你需要一个类型来表示查询条件,Prisma.UserWhereInput 是最合适的选择。

其它方法

400

排除要字段

比如我有一个收藏表,有个外键字段 uid,这个uid其实就是当前登陆用户的id,这个并不需要前端来传递,因为我可以通过上下文获取!

但是因为收藏表中 这个uid是必填的,所以哪怕是我用 Prisma.favoriteCreateInput,最终表现给前端的也是必填项。

但是对于后端来说,这又是合理的。

那就需要我们基于已有的类型,排除这个uid字段了,这个时候我们就可以利用ts类型--排除字段来做了

type favorite= {
  uid: number;
  name: string;
  path: string;
};

// 把 password 去掉
type favoriteExcludeUid= Omit<favorite, 'uid'>;
// 等价于  type favoriteExcludeUid= { name: string; path: string;}

最终落实到项目中,也就是

type CreateFavoriteDto = Omit<Prisma.favoriteCreateInput, 'uid'>;

@Route('api/favorite')
@Tags('favorite')
export class FavoriteController extends Controller {
    /**
     * 新增收藏
     * @summary 创建
     */
    @Post()
    public async create(@Body() favorite: CreateFavoriteDto): ApiResponse<Favorite> {
        const results = await create(favorite);
        return JsonResult.success(results);
    }
}

posted @ 2025-08-18 14:52  丁少华  阅读(67)  评论(0)    收藏  举报