prisma + graphql

接下来为大家介绍使用 prisma + graphql 从0到1实现简单的查询、删除接口。

1. prisma

prisma官方介绍:下一代 Node.js、TypeScript、Go 的数据库 ORM;开源的数据库工具链项目,帮助开发人员更快地构建应用程序并减少错误,支持PostgreSQL、MySQL、MongoDB、SQL Server和SQLite。

可以以对象方式对数据库进行增删改查,十分方便,降低了数据库操作门槛。

参考www.prisma.io/docs/gettin...

安装

bash 复制代码
mkdir hello-prisma
cd hello-prisma
npm init -y
npm install typescript ts-node @types/node --save-dev

# 生成 tsconfig.json文件
npx tsc --init

# 安装prisma
npm install prisma --save-dev

# 生成 prisma/schema.prisma 和 .env 文件,并指定使用的数据库为sqlite
npx prisma init --datasource-provider sqlite

出现如下提示说明命令执行成功

schema.prisma配置文件

schema.prisma 是 Primsa 的主要配置文件,它包含三个基本结构:数据源、生成器、数据模型定义。我们会在此文件中定义数据库的连接信息和模型。且可以用命令将此文件中的表结构同步至数据库,反之亦然。

这里方便起见,将prisma/schema.prisma中的url 地址改为本地文件./dev.db

ini 复制代码
datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
  // url      = env("DATABASE_URL")
}

在prisma/schema.prisma中添加与数据库表匹配的model: User、Post。

完整的prisma/schema.prisma 如下

kotlin 复制代码
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schemagenerator
 client {
  provider = "prisma-client-js"
}
datasource db
 {
  provider = "sqlite"
  url      = "file:./dev.db"
  // url      = env("DATABASE_URL")
}
model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
  posts Post[]
}
model Post {
  id        Int     @id @default(autoincrement())
  title     String  content   String?
  published Boolean @default(false)
  author    User    @relation(fields: [authorId], references: [id])
  authorId  Int
}

与数据库同步

将表结构同步至数据库

perl 复制代码
npx prisma db push

可以看出:同步之后,自动执行了prisma generate ,生成 了Prisma Client。Prisma Client可以用于执行 CRUD 操作。

如果Prisma Schema 文件发生了变动,比如修改、新增了模型,需要做两件事情:同步model至数据库、生成新Prisma Client。执行npx prisma db push 可以两件事情一步到位。

prisma提供了数据库GUI,执行 npx prisma studio 自动打开浏览器,可以看到刚刚创建的2个表。此时表内无数据。

向数据库添加一条记录

尝试创建一条user记录。创建script.ts 文件,并添加内容

javascript 复制代码
// script.ts
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
  
  //这段代码建议手写,以体验Prisma客户端提供的提示功能
  // 以对象形式操作数据库,十分方便
  const user = await prisma.user.create({
    data: {
      name: 'Alice',
      // 按键盘上的CTRL+SPACE键,出现自动提示
      email: 'alice@prisma.io',
    },
  })
  console.log(user)
}

main()
  .then(async () => {
    await prisma.$disconnect()
  })
  .catch(async (e) => {
    console.error(e)
    await prisma.$disconnect()
    process.exit(1)
  })

执行script.ts文件

npx ts-node script.ts

查看GUI,可以看到数据库中生成了记录

可以看出,prisma作为ORM 工具,可以十分方便的实现简单的增删改查。

2. 安装graphql 及相关包

建议将TypeScript与GraphQL搭配一起使用,体验更好。这里使用type-script。

另外,typegraphql-prisma包提供了与prisma的typegraphql集成。 它基于Prisma模式生成类型类和CRUD解析器,可以则需使用。

安装graphql相关

参考typegraphql.com/docs/instal...

matlab 复制代码
npm install type-graphql@2.0.0-beta.1
npm install graphql graphql-scalars
npm install reflect-metadatat

在script.ts文件顶部import

arduino 复制代码
import "reflect-metadata";

安装typegraphql-prisma相关

参考prisma.typegraphql.com/docs/basics...

css 复制代码
npm i -D typegraphql-prisma
npm i graphql-scalars
npm i graphql-fields @types/graphql-fields
npm i tslib

prisma 添加generator typegraphql 相关内容

ini 复制代码
generator typegraphql {
  provider = "typegraphql-prisma"
}

执行命令

npx prisma generate

查看/node_modules/@generated/type-graphql,可以发现生成的ts类型文件。可以择需使用。

安装@apollo/server

graphql 的 npm 包,封装的不够好,一般我们会用基于 graphql 包的 @apollo/server 和 @apollo/client 的包来实现 graphql

bash 复制代码
npm install @apollo/server

实现查询功能

新建resolvers/user.resolvers.ts文件,这里先实现简单的查询功能

typescript 复制代码
import { Query, Resolver } from 'type-graphql';
import {    User} from '@generated/type-graphql';
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient();
@Resolver(User)
export class UserResolver {
    @Query(() => [User])
    async users() {
        return await prisma.user.findMany();
    }
}

tsconfig.json文件内配置改为如下

json 复制代码
{
  "compilerOptions": {
    "target": "es2021",
    "module": "commonjs",
     "lib": ["es2018", "esnext.asynciterable"],
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

script.ts 修改为使用@apollo/server,内容如下

javascript 复制代码
import "reflect-metadata";
import { buildSchema } from 'type-graphql';
import { UserResolver } from './resolvers/user.resolvers';
import { ApolloServer } from "@apollo/server";
import { startStandaloneServer } from "@apollo/server/standalone";
async function bootstrap() {
  const schema = await buildSchema({
    resolvers: [
      UserResolver
    ],
  });
  const server = new ApolloServer({ schema });
  const { url } = await startStandaloneServer(server, {
     listen: { port: 4000 }
   });
  console.log(`GraphQL server ready at ${url}`);
}
bootstrap();

执行npx ts-node script.ts,打开浏览器,操作刚刚的编写的查询接口

实现删除功能

typescript 复制代码
export class UserResolver {
    @Query(() => [User])
    async users() {
        return await prisma.user.findMany();
    }
    @Mutation(() => User, { description: '删除' })
    async UserDelete(
        @Arg('id') id: number,
    ): Promise<User> {
        const user = await prisma.user.delete({
            where: {
                id
            }
        })
        return user;
    }}

之前的例子中,PrismaClient 是在resolver文件中声明。更合适的做法是在外部声明,这样任意resolver文件都可以饮用。这里可以使用context。

修改script.ts 文件如下:

javascript 复制代码
import "reflect-metadata";
import { buildSchema } from 'type-graphql';
import { UserResolver } from './resolvers/user.resolvers';
import { ApolloServer } from "@apollo/server";
import { startStandaloneServer } from "@apollo/server/standalone";
import { PrismaClient } from '@prisma/client'const prisma = new PrismaClient();
export interface Context {
  prisma: PrismaClient;
}
async function bootstrap() {
  const schema = await buildSchema({
    resolvers: [
      UserResolver
    ],
  });
  const server = new ApolloServer({ schema });
  const { url } = await startStandaloneServer(server, {
     context: async () => ({ prisma }),
    listen: { port: 4000 }
   });
  console.log(`GraphQL server ready at ${url}`);
}
bootstrap();

修改resolvers/user.resolvers.ts文件如下

less 复制代码
import { Mutation, Arg, Query, Resolver, Ctx } from 'type-graphql';
import {
    User
} from '@generated/type-graphql';
import { Context } from '../script';

@Resolver(User)
export class UserResolver {
    @Query(() => [User])
    async users(
        @Ctx() { prisma }: Context
    ) {
        return await prisma.user.findMany();
    }
    @Mutation(() => User, { description: '删除' })
    async UserDelete(
        @Arg('id') id: number,
        @Ctx() { prisma }: Context
    ): Promise<User> {
        const user = await prisma.user.delete({
            where: {
                id
            }
        })
        return user;
    }}
相关推荐
耶啵奶膘18 分钟前
uniapp-是否删除
linux·前端·uni-app
王哈哈^_^2 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie2 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic3 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿3 小时前
webWorker基本用法
前端·javascript·vue.js
cy玩具4 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端
qq_390161774 小时前
防抖函数--应用场景及示例
前端·javascript
John.liu_Test5 小时前
js下载excel示例demo
前端·javascript·excel
Yaml45 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事5 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro