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`)
)
最终生成的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.UserCreateInput
和 Prisma.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; };
主要区别
-
字段可选性:
Prisma.UserCreateInput
:某些字段可能是必填的,具体取决于模型定义。Prisma.UserUpdateInput
:所有字段都是可选的,因为更新操作允许部分字段更新。
-
自增字段:
Prisma.UserCreateInput
:不包含自增字段(如id
),因为这些字段由数据库自动生成。Prisma.UserUpdateInput
:同样不包含自增字段,因为这些字段用于标识要更新的记录,而不是更新的内容。
-
用途:
Prisma.UserCreateInput
:用于创建新记录。Prisma.UserUpdateInput
:用于更新现有记录。
userWhereUniqueInput
Prisma.UserWhereUniqueInput
是 Prisma 自动生成的一个类型,用于在更新或删除操作中唯一地标识一个记录。它通常包含模型中定义的唯一字段(如 id
、email
等),这些字段可以用来唯一地定位数据库中的某一条记录。
用途
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
可以确保你在更新或删除操作中使用正确的字段来标识记录,从而避免错误。 - 灵活性:你可以选择使用任何一个唯一字段来标识记录,例如
id
或email
。
总结
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
支持复杂的查询条件,包括逻辑运算符(AND
、OR
、NOT
)和比较操作。
示例:复杂查询条件
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
是最合适的选择。
其它方法
排除要字段
比如我有一个收藏表,有个外键字段 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);
}
}