Skip to main content

定制型号

随着应用的增长,你可能会发现需要将相关逻辑组合在一起。我们建议:

¥As your application grows, you may find the need to group related logic together. We suggest either:

  • 使用 Prisma 客户端扩展 创建静态方法

    ¥Creating static methods using a Prisma Client extension

  • 将模型封装在类中

    ¥Wrapping a model in a class

  • 扩展 Prisma Client 模型对象

    ¥Extending Prisma Client model object

具有 Prisma 客户端扩展的静态方法

¥Static methods with Prisma Client extensions

以下示例演示如何创建将 signUpfindManyByDomain 方法添加到用户模型的 Prisma 客户端扩展。

¥The following example demonstrates how to create a Prisma Client extension that adds a signUp and findManyByDomain methods to a User model.

import bcrypt from 'bcryptjs'
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient().$extends({
model: {
user: {
async signUp(email: string, password: string) {
const hash = await bcrypt.hash(password, 10)
return prisma.user.create({
data: {
email,
password: {
create: {
hash,
},
},
},
})
},

async findManyByDomain(domain: string) {
return prisma.user.findMany({
where: { email: { endsWith: `@${domain}` } },
})
},
},
},
})

async function main() {
// Example usage
await prisma.user.signUp('user2@example2.com', 's3cret')

await prisma.user.findManyByDomain('example2.com')
}

将模型封装在类中

¥Wrap a model in a class

在下面的示例中,你将看到如何将 Prisma 客户端中的 user 模型封装在 Users 类中。

¥In the example below, you'll see how you can wrap the user model in the Prisma Client within a Users class.

import { PrismaClient, User } from '@prisma/client'

type Signup = {
email: string
firstName: string
lastName: string
}

class Users {
constructor(private readonly prismaUser: PrismaClient['user']) {}

// Signup a new user
async signup(data: Signup): Promise<User> {
// do some custom validation...
return this.prismaUser.create({ data })
}
}

async function main() {
const prisma = new PrismaClient()
const users = new Users(prisma.user)
const user = await users.signup({
email: 'alice@prisma.io',
firstName: 'Alice',
lastName: 'Prisma',
})
}

使用这个新的 Users 类,你可以定义像 signup 这样的自定义函数:

¥With this new Users class, you can define custom functions like signup:

请注意,在上面的示例中,你仅从 Prisma 客户端公开 signup 方法。Prisma 客户端隐藏在 Users 类中,因此你无法再调用 findManyupsert 等方法。

¥Note that in the example above, you're only exposing a signup method from Prisma Client. The Prisma Client is hidden within the Users class, so you're no longer be able to call methods like findMany and upsert.

当你拥有大型应用并且你想要有意限制模型的功能时,此方法非常有效。

¥This approach works well when you have a large application and you want to intentionally limit what your models can do.

扩展 Prisma Client 模型对象

¥Extending Prisma Client model object

但是,如果你不想隐藏现有功能但仍想将自定义功能分组在一起怎么办?在这种情况下,你可以使用 Object.assign 来扩展 Prisma Client,而不限制其功能:

¥But what if you don't want to hide existing functionality but still want to group custom functions together? In this case, you can use Object.assign to extend Prisma Client without limiting its functionality:

import { PrismaClient, User } from '@prisma/client'

type Signup = {
email: string
firstName: string
lastName: string
}

function Users(prismaUser: PrismaClient['user']) {
return Object.assign(prismaUser, {
/**

* Signup the first user and create a new team of one. Return the User with

* a full name and without a password
*/
async signup(data: Signup): Promise<User> {
return prismaUser.create({ data })
},
})
}

async function main() {
const prisma = new PrismaClient()
const users = Users(prisma.user)
const user = await users.signup({
email: 'alice@prisma.io',
firstName: 'Alice',
lastName: 'Prisma',
})
const numUsers = await users.count()
console.log(user, numUsers)
}

现在,你可以将自定义 signup 方法与 countupdateManygroupBy() 以及 Prisma Client 提供的所有其他精彩方法一起使用。最重要的是,它都是类型安全的!

¥Now you can use your custom signup method alongside count, updateMany, groupBy() and all of the other wonderful methods that Prisma Client provides. Best of all, it's all type-safe!

更进一步

¥Going further

我们建议使用 Prisma 客户端扩展 来使用 自定义模型方法 扩展你的模型。

¥We recommend using Prisma Client extensions to extend your models with custom model methods.