Primsa Client 单表和多表 CRUD 的全部 api
单表
环境搭建与项目初始化
创建新项目
创建项目目录并初始化:
mkdir prisma-client-api
cd prisma-client-api
npm init -y
初始化 Prisma:
npx prisma init
配置数据库连接
修改 .env
文件中的数据库连接信息:
DATABASE_URL="mysql://root:自己的密码@localhost:3306/prisma_test"
在 schema.prisma
文件中设置数据源和模型:
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model Test {
id Int @id @default(autoincrement())
email String @unique
name String?
}
安装依赖和设置文档生成器
安装文档生成器:
npm install prisma-docs-generator -D
添加文档生成器配置到 schema.prisma
:
generator docs {
provider = "node node_modules/prisma-docs-generator"
output = "../generated/docs"
}
重置数据库并创建迁移:
npx prisma migrate reset
npx prisma migrate dev --name test
初始化 TypeScript 环境
安装 TypeScript 相关包:
npm install typescript ts-node @types/node -D
初始化 tsconfig.json
:
npx tsc --init
在 package.json
中配置 seed
命令:
"prisma": {
"seed": "npx ts-node prisma/seed.ts"
}
生成并查看 API 文档:
npx http-server ./generated/docs
访问 http://localhost:8080
查看生成的文档。
数据初始化
填充初始数据 (prisma/seed.ts):
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient({
log: [
{
emit: 'stdout',
level: 'query',
},
],
});
async function main() {
await prisma.test.createMany({
data: [
{ name: '云牧', email: 'yyy@yyy.com' },
{ name: '黛玉', email: 'ddd@ddd.com' },
{ name: '惜春', email: 'd@d.com' },
],
});
console.log('done');
}
main();
执行数据填充:
npx prisma db seed
CRUD 操作 (src/index.ts)
查找操作
findUnique
findUnique 方法用于查找具有唯一标识的记录。例如,根据主键或具有唯一索引的列:
// src/index.ts
async function test1() {
const userById = await prisma.aaa.findUnique({
where: { id: 1 }
});
console.log(userById);
const userByEmail = await prisma.aaa.findUnique({
where: { email: 'bbb@xx.com' },
select: { id: true, email: true }
});
console.log(userByEmail);
}
test1();
运行:
npx ts-node ./src/index.ts
findUniqueOrThrow
类似于 findUnique,但如果未找到记录,则抛出异常。
findMany
findMany 方法用于查询多条记录。支持排序、分页和条件过滤:
async function test() {
const users = await prisma.test.findMany({
where: { email: { contains: 'd' } },
orderBy: { name: 'desc' },
skip: 0,
take: 3,
select: { id: true, email: true },
});
console.log(users);
}
test();
findFirst
findFirst 方法返回符合条件的第一条记录。它的使用方法与 findMany 类似,但只返回一个结果。
创建和更新操作
create
用于创建新记录。可以通过 select 选择返回特定字段:
async function test() {
const newUser = await prisma.test.create({
data: { name: '宝钗', email: 'bbb@bbb.com' },
select: { email: true },
});
// 由于上面select限制,这里只包含email字段
console.log(newUser);
}
test();
update
更新单条记录。需要指定 where 条件和 data 更新内容:
async function test() {
const updatedUser = await prisma.test.update({
where: { id: 3 },
data: { email: 'xichun@xichun.com' },
select: { id: true, email: true },
});
console.log(updatedUser);
}
test();
updateMany
用于更新多条记录,不返回具体的更新记录:
async function test() {
const updateResult = await prisma.test.updateMany({
where: { email: { contains: 'com' } },
data: { name: '红楼梦' },
});
console.log(updateResult);
}
test();
Upsert
upsert 方法结合了更新(update)和插入(insert)的功能。根据指定条件,该方法会判断是更新现有记录还是创建新记录。
async function test() {
const res = await prisma.test.upsert({
where: { id: 4 },
update: { email: 'xifeng@xifeng.com' },
create: {
id: 4,
name: '王熙凤',
email: 'www@www.com',
},
});
console.log(res);
}
test();
- 第一次执行时,若找不到 id 为 4 的记录,则执行插入操作。
- 第二次执行时,若记录已存在,则进行更新。
删除操作
delete 和 deleteMany 方法用于删除单个或多个记录。
async function test() {
await prisma.test.delete({
where: { id: 1 },
});
await prisma.test.deleteMany({
where: {
id: {
in: [2, 3, 4],
},
},
});
}
test();
执行后只有 id 为 7 的记录了:
统计记录数量
count 方法用于统计符合特定条件的记录数:
async function test() {
const count = await prisma.test.count({
where: {
email: {
contains: 'b',
},
},
});
console.log(count);
}
test();
聚合查询
aggregate 方法用于执行复杂的聚合查询,如计数、平均值、最小值和最大值:我们先插入些数据:首先修改 model:重置数据库
npx prisma migrate reset
prisma db push 后:然后执行插入数据逻辑;
async function test() {
const res = await prisma.test.createMany({
data: [
{
name: 'n1',
email: 'n1@n1.com',
age: 10,
},
{
name: 'n2',
email: 'n2@n2.com',
age: 12,
},
{
name: 'n3',
email: 'n3@n3.com',
age: 14,
},
],
});
console.log(res);
}
test();
聚合查询:
async function test() {
const res = await prisma.test.aggregate({
where: {
email: {
contains: 'com',
},
},
_count: {
_all: true,
},
_max: {
age: true,
},
_min: {
age: true,
},
_avg: {
age: true,
},
});
console.log(res);
}
test();
分组聚合
groupBy 方法允许按指定字段进行分组,并对每个分组执行聚合操作:
async function test() {
const res = await prisma.test.groupBy({
by: ['email'],
_count: {
_all: true,
},
_sum: {
age: true,
},
having: {
age: {
_avg: {
gt: 2,
},
},
},
});
console.log(res);
}
test();
按 email 分组,并计算每个分组的年龄总和,只返回平均年龄大于 2 的分组。
多表
项目设置
首先,创建并初始化一个新的 Node.js 项目,设置如下:
# 创建项目目录
mkdir prisma-more-client-api
cd prisma-more-client-api
# 初始化 Node.js 项目
npm init -y
# 初始化 Prisma
npx prisma init
此操作将生成 .env
和 schema.prisma
文件。接下来,修改 .env
文件中的数据库连接信息:
DATABASE_URL="mysql://root:自己的密码@localhost:3306/prisma_test"
数据模型定义
在 schema.prisma
文件中,配置数据源和 Prisma 客户端,并定义相关的数据模型:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model Department {
id Int @id @default(autoincrement())
name String @db.VarChar(20)
createTime DateTime @default(now())
updateTime DateTime @updatedAt
employees Employee[]
}
model Employee {
id Int @id @default(autoincrement())
name String @db.VarChar(20)
phone String @db.VarChar(30)
departmentId Int
department Department @relation(fields: [departmentId], references: [id])
}
执行数据库迁移:
npx prisma migrate reset
npx prisma migrate dev --name init_migration
CRUD 操作
安装依赖和配置 TypeScript
npm install typescript ts-node @types/node -D
npx tsc --init
在 tsconfig.json
中保留以下配置:
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"types": ["node"],
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}
实现 CRUD 操作
在 src/index.ts
文件中,实现各种 CRUD 操作:
插入数据
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient({
log: [
{
emit: 'stdout',
level: 'query',
},
],
});
async function test() {
await prisma.department.create({
data: {
name: '技术部',
employees: {
create: [
{
name: '小张',
phone: '111',
},
{
name: '小李',
phone: '222',
},
],
},
},
});
}
test();
运行 npx ts-node ./src/index.ts
后:
查询数据
async function queryDepartmentWithEmployees() {
const department = await prisma.department.findUnique({
where: { id: 1 },
include: { employees: true },
});
console.log(department);
}
queryDepartmentWithEmployees();
更新数据
async function updateDepartmentAndAddEmployee() {
const updatedDepartment = await prisma.department.update({
where: { id: 1 },
data: {
name: '销售部',
// 在 employees 关联字段进行操作
employees: {
// 创建一个新员工,姓名为 '小刘',电话为 '333'
create: [{ name: '小刘', phone: '333' }],
// 关联一个 id 为 2 的已存在员工
connect: [{ id: 2 }],
},
},
});
console.log(updatedDepartment);
}
updateDepartmentAndAddEmployee();
删除数据
async function deleteEmployeesOfDepartment() {
const res = await prisma.employee.deleteMany({
where: {
department: { id: 1 },
},
});
console.log(res);
}
deleteEmployeesOfDepartment();
执行直接 SQL
在特定情况下,直接执行 SQL 可能更为直接有效:
async function executeRawSQL() {
// 使用 Prisma 的 $executeRaw 方法来执行一个原生 SQL 命令,清空 Department 表
await prisma.$executeRaw`DELETE FROM Department`;
// 使用 Prisma 的 $queryRaw 方法执行一个查询 SQL 命令,这里是从 Department 表中选取所有记录
const departments = await prisma.$queryRaw`SELECT * FROM Department`;
console.log(departments);
}
executeRawSQL();
转载自:https://juejin.cn/post/7374238968686346266