标题

《小鑫发现》之GraphQL框架Prisma

介绍

这是一个新的前后端交互的方案,不是一定是最好的,但是却很有意思,一种可以让前端人员自由去控制数据库,脱离开后端人员开发SQL读取数据库一层。
虽然不见得能解决所有场景,只有善加利用,很可能解决绝大部分的场景,减少人力,提高效率。
很类似之前的hibernate那种对象的形式操作数据库,其实官网的第一句话,就是“Next-generation ORM
for Node.js and TypeScript”,可知他是个ORM,跟mybatis是一类。去理解如何用对象,或者说 用图的形式去描述数据。

版本和下载

node v15.5.1 下载地址
npm 7.3.0 下载地址

小记

本人在研究过程中发现,通过官方的ts教程,一直报错,原因暂时不知道,主要是不会ts,另外也可能是阿里镜像的问题,即使我删了也是不行,所以这个教程,从下载官方的demo开始。咱们分两步,第一步先构建一个脚本的框架,先去试试Prisma的魅力,第二步,构建一个node服务,框架式Express+Prisma,将其服务化,提供给前端。

初次构建

准备工作

此次咱们使用MySQL,
数据库脚本地址 下载地址
这里直接沾出来,数据库名为mydb,加了点自己的小小创意。

CREATE DATABASE IF NOT EXISTS mydb DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;
USE mydb;CREATE TABLE User (id INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,name VARCHAR(255),email VARCHAR(255) UNIQUE NOT NULL
);
CREATE TABLE Post (id INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,title VARCHAR(255) NOT NULL,createdAt TIMESTAMP NOT NULL DEFAULT now(),content TEXT,published BOOLEAN NOT NULL DEFAULT false,authorId INTEGER NOT NULL,FOREIGN KEY (authorId) REFERENCES User(id)
);
CREATE TABLE Profile (id INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,bio TEXT,userId INTEGER UNIQUE NOT NULL,FOREIGN KEY (userId) REFERENCES User(id)
);INSERT INTO `mydb`.`Post`(`title`, `createdAt`, `content`, `published`, `authorId`) VALUES ('Hello World', '2021-01-21 15:53:37', NULL, 0, 6);INSERT INTO `mydb`.`User`( `name`, `email`) VALUES ('Sarah', 'sarah@prisma.io');
INSERT INTO `mydb`.`User`(`name`, `email`) VALUES ('Maria', 'maria@prisma.io');

然后下载官方的demo,地址是 https://www.prisma.io/docs/getting-started/quickstart-node
根据自己的环境进行下载。mine 是 mac。

下载完毕后,会有start文件夹,结构如下

start
---package.json #这个就不多说,懂则懂,不懂就算了
---prisma # 这是关键,prisma的主要目录,配置都在这里
------dev.db # 这是SQLite需要的,咱们是MySQL版本,所以就让他静静的呆着吧
------schema.prisma # 关键的东西,主要配置都在这里,数据配置啊,对象逻辑啊
---script.js # 这次的使用脚本,后续运行都是这里

官方是SQLite版本,咱们需要做一些改动,改成我这样,你们一定能看懂,我相信你们。
在prisma修改一个.env文件(这里是隐藏文件,记得取消隐藏),里面内容如下

DATABASE_URL="mysql://root:mims@127.0.0.1.2:3306/mydb"

然后编辑schema.prisma,将provider改成mysql

datasource db {provider = "mysql"url      = env("DATABASE_URL")
}generator client {provider = "prisma-client-js"
}

接下来咱们安装依赖,祖传命令 npm install,我这里是去掉了阿里镜像,速度会慢一些,因为我怕阿里镜像有的没有,导致一些问题(别问,问就是我真的试验了好久)

完毕之后,执行 npx prisma introspect

如果大家在这里发现 npx不管用,可以试试 npm install @prisma/cli --save-dev 安装一下环境,我这里是忘记了,怎么出来的,这里就先给大家提示一下,别问,问就是忘了 。

再次查看schema.prisma,文件内容发生了变化,其实就是用过通过命令,让prisma链接数据库,生成对应的对象,很像mybatis-generator。

generator client {provider = "prisma-client-js"
}datasource db {provider = "mysql"url      = env("DATABASE_URL")
}model Post {id        Int      @id @default(autoincrement())title     StringcreatedAt DateTime @default(now())content   String?published Boolean  @default(false)authorId  Intauthor    User     @relation(fields: [authorId], references: [id])@@index([authorId], name: "authorId")
}model User {id      Int      @id @default(autoincrement())name    String?email   String   @uniqueposts   Post[]Profile Profile?
}model Profile {id     Int     @id @default(autoincrement())bio    String?userId Int     @uniqueUser   User    @relation(fields: [userId], references: [id])
}

这里咱们需要改动一下内容,方便咱们后面进行测试。直接上代码,你们可以直接替换就好。主要改动的地方,Post里的 User->aothor,Profile里的User -> user,User里的Post -> posts,Profile -> profile。别问为啥,问就是官方就是这么干的,其实我在想为啥不直接改数据字段名称呢。

datasource db {provider = "mysql"url      = env("DATABASE_URL")
}generator client {provider = "prisma-client-js"
}model Post {id        Int      @id @default(autoincrement())title     StringcreatedAt DateTime @default(now())content   String?published Boolean  @default(false)authorId  Intauthor      User     @relation(fields: [authorId], references: [id])@@index([authorId], name: "authorId")
}model Profile {id     Int     @id @default(autoincrement())bio    String?userId Int     @uniqueuser   User    @relation(fields: [userId], references: [id])
}model User {id      Int      @id @default(autoincrement())name    String?email   String   @uniqueposts    Post[]profile Profile?
}

然后执行 npx prisma generate,去生成client 。注意这里生成的文件路径是这个 /node_modules/.prisma/client/schema.prisma ,主要起作用的也是这个文件所在的文件夹,我的理解。

这里注意,一个关键点,每次改动schema.prisma,都需要执行一次 npx prisma generate,让其重新生成一遍client,这样才会有效果。

至此所有的准备工作都已经准备好了,剩下的就是看下效果了。
修改script.js的内容。

const { PrismaClient } = require('@prisma/client')const prisma = new PrismaClient()// A `main` function so that you can use async/await
async function main() {// 这里是增加的代码,看名字就知道是啥意思了吧const allUsers = await prisma.user.findMany()console.log(allUsers)
}main().catch(e => {throw e}).finally(async () => {await prisma.$disconnect()})

然后执行 npm run dev

神奇数据出来了,大家会发现,好像没啥神奇的,慢慢来,其实从构建到现在咱们没有做逻辑代码编写,都是靠prisma这个框架实现的,接下来介绍用对象的,也是图的方式去描述一下数据,会有什么效果。

继续修改script.js,修改main方法,为这样,这里大家可以理解一下,这个data对象咋回事,运行之后有什么效果,这里就是对象的形式去描述要插入的数据,user,post,写好对应的方法,例如create,就可以直接创建,要是咱们之前方法,是不是都得挨个写一遍insert呢,这里这些官架子都是prisma提供的,查看官方的文档,你就全了解了,用对象的 ,也是图的方式去描述数据,让prisma去操作,这也是GraphQL的理念。

官方api的地址。官方API教程

async function main() {await prisma.user.create({data: {name: "Alice",email: "alice@prisma.io",posts: {create: { title: "Hello World" },},profile: {create: { bio:  "I like turtles" }}}})const allUsers = await prisma.user.findMany({include: { posts: true,profile: true },})console.dir(allUsers, { depth: null })
}

再次执行 npm run dev

$ npm run dev                                                                                                   > script@1.0.0 dev
> node ./script.js[{id: 5,name: 'Sarah',email: 'sarah@prisma.io',posts: [],profile: null},{id: 6,name: 'Maria',email: 'maria@prisma.io',posts: [{id: 4,title: 'Hello World',createdAt: 2021-01-21T15:53:37.000Z,content: null,published: false,authorId: 6}],profile: null},{id: 10,name: 'Alice',email: 'alice@prisma.io',posts: [{id: 6,title: 'Hello World',createdAt: 2021-01-21T08:09:06.000Z,content: null,published: false,authorId: 10}],profile: { id: 2, bio: 'I like turtles', userId: 10 }}
]

服务化构建

这一步开始去改在成Express服务化,依然使用官方的例子,简单直接。

github地址 链接地址

本人是Mac就是直接用命令,Windows可以去下载

curl https://codeload.github.com/prisma/prisma-examples/tar.gz/latest | tar -xz --strip=2 prisma-examples-latest/javascript/rest-express

下载完成之后 ,咱们用webstorm打开,这里大家就会发现其实,目录结构是一样的,多了个src,这个里面有个index.js这个就是咱们需要服务的主文件,以及接口都在这里写。
然后按照之前的教程,修改数据库,然后执行对应的命令,然后修改一下schema.prisma。这里就列出需要执行的命令,数据库和schema.prisma按照之前的教程修改,其实就是把之前的逻辑走一遍。

$ npm install
$ npx prisma introspect
$ npx prisma generate

如果之前的教程都执行没问题,这里就应该没事,然后咱们就去看 src/index.js 。
然后咱们启动一下看看,命令是npm run dev

大家可以试试官方的里面的几个api去测试一下,了解一下如何描述数据对象。我这里开始改造,将其改造为前端直接控制数据对象,通过接口去描述实现查询和创建。
直接上代码。

const express = require('express')
const bodyParser = require('body-parser')
const {PrismaClient} = require('@prisma/client')const prisma = new PrismaClient()
const app = express()app.use(bodyParser.json())app.get(`/user`, async (req, res) => {const result = await prisma.user.findMany({...req.body})res.json(result)
})app.post(`/user`, async (req, res) => {const result = await prisma.user.create({...req.body})res.json(result)
})const server = app.listen(3000, () =>console.log('												

《小鑫发现》之GraphQL框架Prisma相关推荐

  1. sdut-2732 小鑫の日常系列故事(一)——判断对错

    点击打开链接 小鑫の日常系列故事(一)--判断对错 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem ...

  2. 存放在外存上的数据关机后_小鑫话题 | 惊了!关机后SSD会丢数据?

    今天小鑫在群里看到一个很有趣的话题,是关于SSD和HDD哪个更好的讨论.这个话题小鑫都已经见过不下十次了,但是今天小鑫看到了一句以前从没有看到的言论. (某交流群截图) 看到这里,小鑫觉得网络上的&q ...

  3. E - 小鑫の日常系列故事(一)——判断对错

    Description 话说小鑫可是一个奇人,在他刚出生的时候,就能口算出1000000以内的加法.因为他有这样一项能力,他的父母专门雇佣了一位可爱的保姆姐姐(内部消息不超过二十岁哦)来训练他.可是这 ...

  4. Java练习 SDUT-2737_小鑫の日常系列故事(六)——奇遇记

    小鑫の日常系列故事(六)--奇遇记 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 今天,小鑫在山上玩的时候,意外被推下 ...

  5. @scheduled cron启动后和每小时执行_小耶哥: 一个Redis分布式锁又要和小鑫同学扯半个小时!...

    1 Redis分布式锁 |1-1 定时任务重复执行-问题引入 最近小耶哥在做一个功能, 什么功能呢? 就是超时未支付的订单我们要定时关闭, 释放库存, 并且短信通知用户该订单因超时被取消了.由于小耶哥 ...

  6. sdut-3102小鑫追女神

    点击打开链接 小鑫追女神 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Description 小 ...

  7. 小鑫の日常系列故事(六)——奇遇记_JAVA

    Description 今天,小鑫在山上玩的时候,意外被推下了悬崖. 当然,掉下悬崖之后必然有奇遇.(剧情就是这么坑爹)就狗血的碰到了野人A和野人B.然后两位野人就给了他一本武功秘籍. 这是一本强大的 ...

  8. 小鑫の日常系列故事(十)——排名次_JAVA

    Description 小鑫在来到SDUT之后,经过十分刻苦的学习和努力终于进入了ACM集训队.很快又一次ACM集训队的选拔就要开始了,集训队员们又忙碌了起来.他也十分幸运的被学长抓来当苦力. o(∩ ...

  9. 小鑫与斐波那契(一)

    小鑫与斐波那契(一) Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 相信大家都知道斐波那契数列问题.但是小鑫不知道.(这是一个悲 ...

  10. 今天微信小程序发现wx.request不好使了,调试报错: 小程序要求的 TLS 版本必须大于等于 1.2...

    今天微信小程序发现wx.request不好使了,调试报错: 小程序要求的 TLS 版本必须大于等于 1.2 查官方文档 解决方法 在 PowerShell中运行以下内容, 然后重启服务器 # Enab ...

最新文章

  1. 8个可以提高数据科学工作效率、节省宝贵时间的Python库
  2. 用PHP实现var_export
  3. 设置树莓派SSH连接因超时闲置断开(转)
  4. 下拉选项框选中之后,通过ajax请求服务器,填充页面其他元素的value值
  5. “云时代架构”经典文章阅读感想十二
  6. Python __dict__和vars()
  7. 亚马逊S3文件存储的可视化
  8. 变了,iPhone 12变身iPhone 4模样;下一代只支持单种5G频段?
  9. JAVA屏幕截图与水印添加程序-HEHEHEScreenshot
  10. BZOJ 2431: [HAOI2009]逆序对数列( dp )
  11. qt deleterLater
  12. 卡巴斯基KEY大集合
  13. 技术分析:细说3D投影机技术原理
  14. 51单片机存储器结构
  15. 微信公众号跳转到指定的第三方微信小程序页面
  16. 第4周收录188起融资,国内物流暴涨,国外40起过亿元大额融资 | 潜在周报
  17. python中axis的理解
  18. Minecraft 1.19.2 Forge模组开发 07.拼图建筑(jigsaw)
  19. python爬虫学习 之 定向爬取 淘宝商品价格
  20. js继承(ES5,ES6)

热门文章

  1. android 的一些编译问题
  2. 腾达n6路由器虚拟服务器设置,腾达n6路由器怎么设置带宽控制
  3. Final IK详解
  4. 医学图像笔记(八)窗宽窗位
  5. 7.2 可分离变量的微分方程
  6. 基于阿里DDNS的ipv6 for windows版软件
  7. 云服务器带宽是什么 云服务器带宽怎么选
  8. python结巴分词 每个词一行,python-结巴分词+词云展示
  9. YunCharging充电桩系统开源源码,配套设备+小程序直接商用落地
  10. CN域名海外注册商体系(7)2010年4月2日资料