问题场景
如果定义一张表
model user{
id BigInt @id @default(autoincrement())
name string
}
那么我们直接读取该表中的数据FindMany
const prisma=new prismaClient()
let users=prisma.user.findMany()
console.log(users)
//响应结果
/*
[{id:1n,name:jack},{id:2n,name:Cindy}]
*/
这里我们发现读取到的id值返回为BigInt类型,如果我们将改结果直接响应给客户端,则会报以下错误!
这是因为我们将结果返回给客户端需要进过JSON处理,而我们的JavaScript不支持直接将Bigint类型数据序列化,因此造成以上的错误信息!
解决方案
这里我们将使用Prisma Client中的中间件来实现对查询数据库结果的序列化!
1.首先我们封装一个prismaService
import { Injectable } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient {
constructor() {
//输出查询SQL等LOG
super({ log: ['query', 'info', 'warn', 'error'] });
}
}
2.调用super.$use()方法来使用中间件
prsima.$use()方法出自官方文档
3.创建好一个可迭代序列化Object的方法
serialize(obj) {
if (typeof obj === 'bigint') {
return parseInt(`${obj}`); // 将BigInt值转换为字符串,'n'作为标记表示这是一个BigInt
} else if (typeof obj === 'object' && obj !== null) {
return JSON.parse(
JSON.stringify(obj, (key, value) => {
if (typeof value === 'bigint') {
return parseInt(`${value}`);
}
return value;
}),
);
}
return obj; // 对于非对象类型,直接返回
}
4.整合中间件 嵌入到prismaService中
最终得出prsima.service.ts
import { Injectable } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient {
constructor() {
//输出查询SQL等LOG
super({ log: ['query', 'info', 'warn', 'error'] });
// 利用中间件对查询数据库的结果Bigint类型进行序列化!
super.$use(async (params, next) => {
const before = Date.now();
const result = await next(params);
const after = Date.now();
console.log(
`Query ${params.model}.${params.action} took ${after - before}ms`,
);
return this.serialize(result);
});
}
serialize(obj) {
if (typeof obj === 'bigint') {
return parseInt(`${obj}`); // 将BigInt值转换为字符串,'n'作为标记表示这是一个BigInt
} else if (typeof obj === 'object' && obj !== null) {
return JSON.parse(
JSON.stringify(obj, (key, value) => {
if (typeof value === 'bigint') {
return parseInt(`${value}`);
}
return value;
}),
);
}
return obj; // 对于非对象类型,直接返回
}
}
因此所有经过prisma查询的数据结果都会经过serialize方法进行Bigint的序列化
自我学习 代码如有问题 多多指出 有更好的方案或优化一起交流